Elecfans高手问答Q&A——ARM问答
本帖非活动贴,我们将活动中的Q&A做了整合,方便大家共同学习。
Elecfans社区问答已经在大家的积极参与下全面展开,我们会在每一期活动结束后,将帖子中的精华问答整合于此,方便大家翻阅,共同学习,共同进步。
************************为了给大家一个方便的阅读环境,请不要在本帖回复,谢谢配合***********************
高手问答第8期——ARM问答
活动时间:2014.8.18-2014.8.25
活动链接:http://bbs.elecfans.com/jishu_446916_1_1.html
******************************************问答收录**************************************************
Q:我用TQ2440开发板和我的虚拟机链接,能ping的通,但是就是mount不上,nfs配置好了,桥接也选上了,linux和windows的防火强也都关闭了,可就是mount不上,请问这是什么原因,该怎么去解决?@lihaolongli
A:这个问题遇到多次,无非就是防火墙和配置的问题,重新确认是否完全关闭了windos和虚拟机的防火墙,确认windos、虚拟机和开发板三者均可相互ping通,确认nfs配置文件正确,基本就可解决该问题
Q:下载LCD驱动到开发板上出现failed to find bootloader framebuffer,请问是什么原因造成的呢
A:尽可能把问题描述详细些吧,起码,把你所使用的环境告诉大家吧?比如,用的什么开发板?什么片子?
Q:FM24C64和EEPROM AT24C04 在读写上有什么区别 我用的是LPC1778.知道的,请指教。谢谢。@lihaolongli
A:FM24C64和EEPROM AT24C04 在读写上有什么区别 我用的是LPC1778.知道的,请指教。谢谢。@lihaolongli
Q:LPC1768的定时器定时精度在手册上并没有具体给出,但是附带例程上的程序初始化是这样的:
void timer0Init (void)
{
T0TCR = 0x02;
T0IR = 1;
T0CTCR = 0;
T0TC = 0;
T0PR = 0;
T0MR0 = FPCLK/2; /* 0.5S中断1次 */
T0MCR = 0x03; /* 匹配后产生中断 */
T0TCR = 0x01; /* 启动定时器 */
}
其中外设时钟频率FPCLK=24MHz(晶振是12MHz),PR=0,所以延时时间是1/FPCLK*(PR+1)*(MR0+1)约等于0.5S。
是不是意味着这个定时器的精度就是将PR和MR的值取最低为0,得到精度为1/24微秒呢?
我想用这个定时器实现定时然后中断在DA管脚输出一个模拟值,能够达到0.1微秒输出一个点是预期想要达到的效果,但是每次调整PR和MR值时最低差不多是0.5微秒就到极限了,并且输出的模拟值经DA转换后还存在波形重叠等现象,到底该如何解决这个问题呢?能不能单独的将数组存放在一个数据存储器中,然后定时0.1微秒中断从数据存储器中取出一个数送到DA管脚?大神们有没有什么办法?谢谢了。
我用的C语言编程,KEIL开饭环境,自己想到的原因也就是程序进出中断函数也需要时间,可能是ns级别,所以导致输出波形重叠啥的,,,别的原因就想不出来了,,,,@lihaolongli 求指导
A:理论上是这样的,不过,24M的频率相对还是低了些,中断里的处理会有一些时间延迟,表现出来的现象就是定时频率越高延迟越明显,只能尽可能减少中断内部的处理,接近理论值,这算是硬伤了……
Q:LPC2294的P0.1和P0.0作为串口接收单片机发来的按键值keynum(0x01,0x02......),不知道程序哪里有问题,1)单片机发出来的数据用串口调试助手可以收到,为什么ARM收不到,2)还有就是U0FCR 设置为触发点为1个字节对不对,按键值在单片机定义的是char型?3)单片机发给串口调试助手比如10是0A,11是0B,那么ARM接收到也是这样吗?由于才接触ARM希望指导下@lihaolongli 。band为9600,单片机也是9600
void UART0_Ini(uint32 baud)
{
uint32 bak;
PINSEL0 = PINSEL0 | 0x00000005; //使用P0.0-TXD(UART0)和P0.1-RXT(UART0)
U0LCR = 0x83; // DLAB位置1
bak = (Fpclk >> 4) / baud;
U0DLM = bak >> 8;
U0DLL = bak&0xff;
U0LCR = 0x03; //字长选择8bit,清DLAB,无奇偶校验;
U0FCR = 0x01; // 使能FIFO,设置触发点为1字节,并复位RXFIFO
U0IER = 0x01; // 允许RBR中断,即接收中断
//设置中断允许
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICVectCntl1 = 0x26; // UART0中断通道分配到IRQ slot 1,即优先级second
VICVectAddr1 = (uint32)IRQ_UART0; // 设置UART1向量地址
VICIntEnable = (1<<6); // 使能UART0中断
}
void __irq IRQ_UART0(void)
{
uint8 i;
uart0=1;
if( (U0IIR&0x0F)==0x04)
{//接收字节数达到接收FIFO中的出发点(RDA)中断
keynum = U0RBR;
}
else
{//接收超时(CTI)中断
U0FCR=0XC3; //bit2 = 1,清空UARTn接收FIFO,并使指针逻辑复位
}
VICVectAddr = 0x00; // 中断处理结束
}
A:从你的描述上看,问题出在LPC2294上,解决办法:1、检查UART初始化是否正确(参考手册,例程)2、让LPC2294这边串口接收到什么原样发送出去,通过串口助手看数据是否正确3、还可以在线调试,串口中断里设置断点,观察下变量是否正确
Q:我用的是奋斗STM32开发板,最近在学习RTC和EXTI的时候,仿照例程做了一个定时器程序,开发板上用两个LED分别表示秒中断和定时时间到达,四个按键:K1的功能是开始设置和结束设置,走的是EXTI线5,按一下开始设置,再按一下将计数值写入Alarm寄存器;K2的功能是当前时钟加1分钟,走的是EXTI线2;K3的功能是已设定的时钟减一分钟,走的是EXTI线3;K4的功能是取消设置,走的是EXTI线6。
可是现在除了表示秒中断的LED正常闪烁外,按其他功能键似乎都没有作用,按下K1后秒中断的LED可能会长亮或长暗。我想用JLINK Debug,可是根本打不了断点。
我想请教一下:1)程序里面用到了6个中断(两个RTC中断和4个EXTI中断),它们的NVIC优先级应该如何设置?2)为什么打断点根本没用?3)程序的确也在跑,几个功能键似乎不起作用,问题可能出在哪儿?
敬请赐教@lihaolongli !
A:可以在misc.c文件中调用中断优先级配置程序NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
Q:STM32F407板卡,USB、Micro SD卡,加USRT 和AD采集。应用程序已经编写完毕,想编写一个插入USB,检测烧写文件(output.hex),如果检测到该文件就进行程序更新。 目前我的思路:板卡家电启动后,程序从片内flash里搬到RAM内执行,一旦插入U盘,检测U盘内是否有 output.hex文件,如果有就把它读一段程序写入flash,再读一段再写进flash。直到该文件的数据完全读尽。如果新程序比源程序大就O了,如果比原程序小就把剩下的falsh的数据擦掉。
我上网查了一下,都说要做段引导程序,再做更新。不知道用哪种方法好。求@lihaolongli 支个招。
A:比较好的办法,如果你程序不是太大的话,在FLASH后半部分存储你要更新的程序,在你应用程序中将U盘文件读取出来,放到这个区域,然后软件复位单片机,这里,还要一段引导程序,复位后,先执行引导程序,里面将你写在FLASH中的程序读取并写入到应用程序的位置,这样你程序便能实现U盘升级
Q:请问在2132中想往1602上的DB0--DB7分别连接在2132中的p01--p08,如何定义往p01--p08中写命令,例如单片机中可以PO=data,然后data=0x80,那ARM2132中呢?
A:方法是,可以利用置位寄存器和清零寄存器,这两个寄存器都是写1有效,所以,你可以用这两个寄存器,宏定义一下
Q:我们都知道每一个寄存器都有地址,STM32的寄存器就有32位的长度,而地址也有三十二位的长度,有时候各位会不会这样想:是不是每个寄存器的地址就是寄存器存放数据的地方呢?我们改变某一个寄存器是不是就是改变了某个地址的数值?
我刚开始也是这样想,但是后来发现了问题,比如stm32的GPIOF的首地址是:0x4001 1C00,F口的CRH的寄存器的偏移量的是0X04,CRH是一个32位的寄存器,那么按照上面的想法,CRH就应该对应着32位的地址,但是我们发现,CRH临近的寄存器是CRL和IDR,他们各自的偏移量是0X00,0X08,就是说他们之间只是相差了4个单位,而不是32个,这就有问题了,就是说寄存器并不是地址代称。
上面说得有点乱,我不知道大虾能不能够弄明白我在说什么,希望能够弄明白我在说什么的同道,能够给我一些建议,到底寄存器是不是地址,如果是地址,那么他们之间为什么相差的是4,而不是32,
A:其实这里的4是偏移了四个字节,算出了下一个寄存器的起始地址
Q:作为一个小白,想问几个问题:
1.用jlink进行debug时,下载程序到哪里了?在链接脚本中设置的地址和程序实际运行的地址有什么关系?
2.禁止MMU、关闭看门狗、设置SVC模式之后是不是可以直接操作I/O口的寄存器而不必须初始化时钟?
A:时钟还是要初始化的
看看,希望能有所收获。