基于AT91SAM7se512的串口通讯的实现
来源:互联网 发布:点点客人人店登陆端口 编辑:程序博客网 时间:2024/06/07 05:13
实验室正在研究基于AT91SAM7se512芯片的无人机系统和基于SImulink的无人机飞行仿真平台,主控制芯片与外围传感器的通讯和主控芯片与PC机的通讯是本项目最基本的部分,下面将此段时间对串口通信的认识记录下来,由于本人知识水平的有限,欢迎各位读者积极指正,我将不胜感激。
(一)、硬件部分.
在AT91SAM7se512的串口通信过程中,我使用的是usb转串口线,单一的232串口还是不能和主控芯片连接的,因为二者的电平不一样,232的电平为:高电平=-(3~15)V,低电平=+(3~15)V,而主控芯片的电平为TTL电平,高电平=3V,低电平=0V。所以在串口通信中,必须使用一块232电平转TTL电平的芯片,这里采用的是ADM3202,ADM3202是四通道的TTL转RS232电平的芯片。
由于AT91SAM7se512的两个串口在系统中已经使用,这里选择DBGU口的串口功能做的实验。
(二)、软件的实现
因为在串口发送和接收过程中,中断方式有利于提高cpu的利用率,所以在此选择中断方式。
2.1 初始化
在串口的初始化程序中,需要对串口的IO引脚分配、电源管理、串口配置、AIC中断配置和使能、PDC的设置和DBGU中断的使能进行设置。初始化程序如下所示:
void AT91F_DBGU_Simulink_Init(void){ AT91F_DBGU_CfgPIO(); AT91F_DBGU_CfgPMC(); AT91F_US_Configure ((AT91PS_USART)AT91C_BASE_DBGU, AT91B_MCK, AT91C_US_ASYNC_MODE,115200, 0); AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN; AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_SYS, DBGU_USART_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, Debug_Simulink_irq_handler); AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS); // Set the PDC AT91F_PDC_Open (AT91C_BASE_PDC_DBGU); //* address to the next bloc to be received AT91C_BASE_DBGU->DBGU_RPR = (unsigned int) simulink_queue; AT91C_BASE_DBGU->DBGU_RCR = SIMULINK_NUM;//* 137个字符 //* and AT91C_US_ENDRX AT91F_DBGU_InterruptEnable(AT91C_BASE_DBGU,AT91C_US_RXBUFF );//* RX Buffer Full Interrupt Enable // 字符串形式}以上各个函数和参数在lib_AT91SAM7se512.h、T91SAM7se512.h中定义的,Debug_Simulink_irq_handle为中断服务程序,simulink_queue和SIMULINK_NUM为接收缓冲区及其大小,在此使用的中断触发为RXBUFF(接收缓冲区满)和TXBUFE(发送缓冲区空),RXBUFF中断在初始化中使能,而TXBUFF中断在主函数中使能,稍后会有讲解。
2.2中断服务程序
中断服务程序Debug_Simulink_irq_handle如下:
void Debug_Simulink_irq_handler(void){AT91PS_DBGU USART_pt = AT91C_BASE_DBGU;unsigned int status;//* get Usart status register and active interruptstatus = USART_pt->DBGU_CSR ;//获得通道状态 status &= USART_pt->DBGU_IMR;//去掉屏蔽的状态if ( status & AT91C_US_RXBUFF)//如果是RXBUFF,则设置DBGU_RPR和DBGU_RCR{ AT91C_BASE_DBGU->DBGU_RPR = (unsigned int) simulink_queue; AT91C_BASE_DBGU->DBGU_RCR = SIMULINK_NUM; simulink_flag=1; } if ( status & AT91C_US_TXBUFE)//如果是TXBUFE,则设置DBGU_TPR和DBGU_TCP{ AT91F_DBGU_InterruptDisable(AT91C_BASE_DBGU,AT91C_US_TXBUFE ); to_simulink_transmit_flag=true; AT91C_BASE_DBGU->DBGU_TPR = (unsigned int)NULL; AT91C_BASE_DBGU->DBGU_TCR = 0; } //* Reset the satus bit for error USART_pt->DBGU_CR = AT91C_US_RSTSTA;//错误状态位复位}
2.3 主函数
void main(void ){//初始化函数 for(; ; )//主循环 { //省略若干 if (simulink_flag == 1) { deal_simulink_data();//处理从PC机发送到控制芯片的数据 simulink_flag = 0; } //省略若干 output2simulink();//发送数据到PC机 }}
其中deal_simulink_data()函数和output2simulink()函数如下:
void deal_simulink_data(void){ char save_line[SIMULINK_NUM],*line=NULL;// 不指空 死机? strncpy( save_line, simulink_queue,SIMULINK_NUM ); line=save_line;//line指向接收到数据的存储地址 //省略若干 }
void output2simulink(void){ int len=3; if(to_simulink_transmit_flag==true) { //-------------------control mode------------------------------------ put2simulink[len++]=','; put2simulink[len++]=control_mode+48; //--------------------PWM-------------------------------------------- for(int i = 0;i < 4;i ++) { put2simulink[len++] = ','; len += sprintf(put2simulink+len,"%4d",sim_servo_widths[i]); } put2simulink[len++]='\r'; put2simulink[len++]='\n'; to_simulink_transmit_flag=false; AT91C_BASE_DBGU->DBGU_TPR = (unsigned int)put2simulink; AT91C_BASE_DBGU->DBGU_TCR = len; AT91F_DBGU_InterruptEnable(AT91C_BASE_DBGU,AT91C_US_TXBUFE );//开TXBUFE中断 }}
(三)总结
使用串口调试助手即可以实现PC与ARM板的通信,如果想用其他串口来检测从PC发送到ARM的数据是否正确,检测ARM是否正常接收了由PC发送来的数据,这里有两种方法:
1 、使用IAR中的调试功能,在处理接收数据的地方加一句调试语句printf("%s",line);在Terminal I/O中可以看到输出的字符串。
2、使用其他串口将PC发送到ARM版的数据在发送到PC端,用串口调试助手既可以看到。
在以上两种方法中,我更加喜欢第二种,因为第一种的printf函数占用的调试时间太长,而第二种可以实际反应出程序运行时间情况。
在检测过程中,有几种情况可能导致数据不正确:
1、PC端与ARM板的波特率没有对应起来,这是最容易发现的,也是最容易解决的,将二者的波特率设为一样即可。
2、程序中各个缓冲区的长度不对,这是比较难找的问题,就是因为这个问题,我花了很长的时间才解决好这个问题,本以为检测用的缓冲区的定义的长度只要足够大即可,其实不然,PC端发送字符串的长度、ARM中接收缓冲区定义的长度,实际使用缓冲区的长度、ARM中另一个串口发送字符串的缓冲区定义的长度、实际使用的长度要一致,这里最容易忽略的地方是两个缓冲区的定义的长度,当定义的长度与实际接收的字符串的长度不同的时候,会出现周期性乱码的现象,具体原因我还不明白,希望各位高手指教。
- 基于AT91SAM7se512的串口通讯的实现
- 基于VB的串口通讯及其软件实现
- 基于java数据采集串口通讯的设计和实现
- 基于FPGA的串口通讯设计与实现
- 基于rs232串口通讯的Verilog设计
- 基于rs232串口通讯的Verilog设计
- VC2010基于MSComm32控件的串口通讯
- 基于FPGA的串口通讯设计
- VB中串口通讯的实现
- C#能不能实现串口的通讯
- Windows CE串口通讯类的实现
- Delphi 中串口通讯的实现
- Delphi 中串口通讯的实现
- Delphi 中串口通讯的实现
- VB中串口通讯的实现
- 串口通讯的CRC算法与实现
- 基于PC/104的多串口通讯的设计
- 基于WIN32 API的串口通讯软件的设计
- java性能影响因素
- 程序设计的编程原则
- Java多线程(四)、线程池
- sqlConnectionString连接字符串各个名称解释
- 解决Referenced file contains errors(struts-2.0.dtd)
- 基于AT91SAM7se512的串口通讯的实现
- 一些有用的链接(持续更新)
- 我对广播的理解:在manifset文件中注册广播组件
- CR3,PDE,PTE,TLB
- MyEclipse 10安装svn插件
- Java多线程(五)、多线程其他知识简要介绍
- (step5.2.1)hdu 1251(统计难题)
- 工厂方法模式与抽象工厂模式的区别
- NoSQL技术流派的未来:HBase或将独霸?