用smartarm2200进行串口中断调试,单步执行时可进入终端,且中断程序执行准确,但一旦全速运行,就出行串口接收数据错误。望指教<br /><br /><br />#include "config.h" <br />#define UART_BPS 9600; //定义通信波特率<br />#define LEDCON 0xf0000000; <br />uint8 rcv_buf[8];<br /><br />uint8 rcv_new;<br />/*volatile uint8 rcv_new;*/<br /><br />void DelayNS(uint32 dly)<br />{<br /> uint32 i;<br /> for(;dly>0;dly--)<br /> {<br /> for(i=0;i<5000;i++);<br /> }<br />}<br /><br />/*<br />uint8 UART0_RcvByte(void)<br /><br />{ uint8 rcv_data;<br /><br />while((U0LSR&0x01)==0); //U0RBR为空的话, 一直等待<br /><br />rcv_data=U0RBR; //数据保存在串口0的一位寄存器中<br />return(rcv_data);<br />}<br /><br />void UART0_RcvStr(uint8 *s,uint32 n) //以n个字节为一字符串,n由main函数中给出<br />{<br /> for (;n>0;n--)<br /> { *s++=UART0_RcvByte();<br /> }<br /> } <br /> */<br /> <br /> void UART0_SendByte(uint8 data)<br /> {<br /> U0THR=data;<br /> while((U0LSR&0x40)==0);<br /> }<br /> void UART0_SendBuf(uint8 *str)<br /> { while(1) <br /> { if(*str=='\0')<br /> break;<br /> UART0_SendByte(*str++);<br /> }<br /> }<br /> void UART0_Init(void)<br />{ <br /><br /> uint16 Fdiv;<br /><br /> U0LCR = 0x83; // DLAB = 1,可设置波特率<br /> Fdiv = (Fpclk / 16) / UART_BPS; // 设置波特率<br /> U0DLM = Fdiv / 256; <br /> U0DLL = Fdiv % 256; <br /> U0LCR = 0x03; <br />} // 初始化串口模式<br /><br /><br /> void __irq IRQ_UART0 (void)<br />{<br /> uint8 i,j,k;<br /> uint8 temp; //取得的数据<br /> uint8 strlen; //所需数据长度<br /> uint8 checksum;<br /> uint8 h1,h2,h3; //h1,h2半字节校验,h2放高字节累加和校验,h1放低字节累加和校验<br /> uint8 check_buf[2];<br /> uint8 *p;<br /> uint8 SendStr_1[]="OK!\r\n";<br /> uint8 SendStr_2[]="wrong!\r\n" ;<br /> uint8 SendStr_3[]="Resend\r\n";<br /> IO2CLR=0xf0000000;<br /> /*IO2DIR=0xf0000000;<br /> IO2CLR=0xa0000000; */ //测试是否进中断用,实验结果表明可进入中断 2008 9.24<br /> <br /> if ((U0IIR & 0x0F) == 0x04); <br /> rcv_new = 1; // 设置接收到新的数据标志<br /> /*IO2DIR=0xf0000000;<br /> IO2CLR=0xa0000000;*/ //再次测试串口是否能进入中断,实验结果可行 2008 9 24<br /> for (i=0; i<8; i++)<br /> {<br /> rcv_buf = U0RBR; // 读取FIFO的数据,并清除中断<br /> <br /> }<br /> if(rcv_buf[0]==0x24) // 接收到开始字符$<br /> { <br /> checksum=0;<br /> for(strlen=0;strlen<6;strlen++) //半字节校验<br /> {<br /> checksum=checksum^rcv_buf[strlen+1]; <br /> h2=checksum&0x0F;<br /> h1=((checksum>>4)&0x0F);<br /> <br /> }<br /> h3=(h1<<4)^h2;<br /> if(h3==rcv_buf[7]) //累加和校验通过<br /> {<br /> for(j=2;j<7;j++) //将数据再次返回上位机,进行再次验对<br /> UART0_SendByte(rcv_buf[j]);<br /> <br /> <br /> rcv_new=0; //清楚接收标志位,等待上位机的回应<br /> U0FCR=U0FCR|0x07; //复位Rx FIFO 和Tx FIFO<br /> while((U0LSR&0x01)==0); //U0RBR 为空的话,一直等待<br /> rcv_new=1;<br /> for(k=0;k<2;k++)<br /> { temp=U0RBR;<br /> check_buf[k]=temp; } //将上位机返回的check值,放入buf中,U0RBR中每次只能放一个字节<br /> p=check_buf;<br /> <br /> if (strcmp(p,"OK")==0)<br /> { rcv_new=1; //接收到验证码,通过上位机的验证<br /> UART0_SendBuf(SendStr_1); //返回确认信号,提醒上位机准备开始记录<br /> rcv_new=0; //清楚接收标志位<br /> U0FCR=U0FCR|0x07; //复位Rx FIFO 和Tx FIFO <br /> switch(rcv_buf[6]) //根据上位机给出的激励电流值大小 <br /> <br /> {<br /> case 0x31: //电流值为1A<br /> IO1SET=0x200000; //p1.21<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x10000000;<br /> break;<br /> case 0x32: //电流值为2A<br /> IO1SET=0x400000; //p1.22<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x20000000;<br /> break;<br /> case 0x33: //电流值为3A<br /> IO1SET=0x600000; //p1.21 p1.22<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x30000000;<br /> break;<br /> <br /> case 0x34: //电流值为4A<br /> IO1SET=0x800000; //p1.23<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x40000000;<br /> break;<br /> <br /> case 0x35: //电流值为5A<br /> IO1SET=0xA00000; //p1.21 p1.23<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x50000000;<br /> break;<br /> <br /> case 0x36: //电流值为6A<br /> IO1SET=0xC00000; //p1.23 p1.22<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x60000000;<br /> break;<br /> <br /> case 0x37: //电流值为7A<br /> IO1SET=0xE00000; //p1.21 p1.22 p1.23<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x70000000;<br /> break;<br /> <br /> case 0x38: //电流值为8A<br /> IO1SET=0x1000000; //p1.24<br /> IO2SET=0xf0000000;<br /> IO2CLR=0x80000000;<br /> break;<br /> }<br /> <br /> }<br /> else //数据验证错误<br /> UART0_SendBuf(SendStr_3);<br /> U0FCR=U0FCR|0x07; <br /> <br /> }<br /> <br /> <br /> <br /> else //累加校验不通过<br /> // UART0_SendByte(h2); //将0换为rcv_buf[3],作为实验之用,实验结果表明正确,在半字检验未通过时,返回值正确 2008 9 24<br /> UART0_SendBuf(SendStr_2); //调整程序,使得返回值更实际 2008 9 25<br /> U0FCR=U0FCR|0x07; //复位Rx FIFO 和Tx FIFO<br /> <br /> }<br /> <br /> else<br /> UART0_SendBuf(SendStr_3); <br /> U0FCR=U0FCR|0x07; //复位Rx FIFO 和Tx FIFO <br /> <br /> VICVectAddr = 0x00; // 中断处理结束<br /> }<br /><br /><br /><br /><br />int main(void)<br />{ <br /> /* rcv_new=0;*/<br /> PINSEL0 = 0x00000005; // 设置I/O连接到UART0<br /> IO1DIR=0x1ff0000; //p1.16-p1.24为输出 I/O<br /> IO2DIR=0xf0000000; //p2.28-p2.31为输出 LED<br /> //IO2DIR=LEDCON; // 配置LED控制为输出<br /> <br /> UART0_Init();<br /> U0FCR=0x81; //触发点为8字节,且使能对于FIFO的访问<br /> U0IER=0x01; //使能RDA中断<br /> <br /> <br /> VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断<br /> VICVectCntl0 = 0x26; // UART0中断通道分配到IRQ slot 0,即优先级最高<br /> VICVectAddr0 = (uint32)IRQ_UART0; // 设置UART0向量地址 <br /> VICIntEnable = 0x00000040; // 使能串口中断<br /> <br /> <br /> <br /> while(1); // 等待中断 <br /> return(0);<br /> }<br /><br /> |
|