程序目标:实验中在调试程序时,需要在只用到一个串口的条件下,用上位机同时向单片机传送多个不同数据。
实现原理:1,用LabView编写的上位机,使用VISA向单片机中写入数据;多个数据之间用一些分隔符进行区分。
2,定义一个字符串USART_RX_BUF[]接收收据,然后在该字符串中查找相应的分隔符并得到它们在字符串中的位 置,最后根据这些位置从字符串中提取出相应的字符串,这样就可以得到在上位机中输出的几种不同的数据。
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else
{
USART_RX_STA|=0x8000;//接收完成了
LEN=USART_RX_STA&0x3FFF;
}
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif
int main(void)
{
char *P,*I,*D;
char FQ[12],KP[8],KI[8],KD[8];
u8 x,y,z;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200);//串口初始化为115200
LCD_Init(); //初始化LCD
POINT_COLOR=BLUE;//设置字体为蓝色
memset(FQ,'\0',sizeof(FQ)); //将字符数组设为空字符数组
memset(KP,'\0',sizeof(KP));
memset(KI,'\0',sizeof(KI));
memset(KD,'\0',sizeof(KD));
while(1)
{
if(USART_RX_STA&0x8000) //串口接收状态标志位就绪
{
LCD_Fill(30,250,230,250+16,WHITE); //清空指定区域
LCD_Fill(30,270,230,270+16,WHITE);
LCD_Fill(30,290,230,290+16,WHITE);
LCD_Fill(30,310,230,310+16,WHITE);
P=strrchr((char*)USART_RX_BUF,'p'); //查找字符串中字符'p'的位置,并返回最后一次指向该字符串的指针
I=strrchr((char*)USART_RX_BUF,'i');
D=strrchr((char*)USART_RX_BUF,'d');
x=(u8*)P-USART_RX_BUF;//得到字符'p'在字符串中的偏移量,从而得到第一段字符串的长度
y=(u8*)I-(u8*)(++P); //得到字符'i'在以P为首地址的字符串中的长度,从而得到第二段字符串的长度
z=(u8*)D-(u8*)(++I);
memcpy(FQ,USART_RX_BUF,x); //从接受到的字符串中复制第一段字符串
memcpy(KP,P,y);//从接受到的字符串中复制第二段字符串
memcpy(KI,I,z);//从接受到的字符串中复制第三段字符串
LCD_ShowString(30,250,200,16,16,(char*)FQ); //在LCD上显示第一段字符串
LCD_ShowString(30,270,200,16,16,(char*)KP);
LCD_ShowString(30,290,200,16,16,(char*)KI);
LCD_ShowString(30,310,200,16,16,(++D));//在LCD上显示第四段字符串
USART_RX_STA=0; //清空状态标志位
for(i=0;i' '; //将接受的字符串清空
memset(FQ,'\0',sizeof(FQ)); //将字符数组设为空字符数组
memset(KP,'\0',sizeof(KP));
memset(KI,'\0',sizeof(KI));
memset(KD,'\0',sizeof(KD));
}
delay_ms(10);
}
}
程序运行结果:LabView中输入的四种数据,在单片机中都分别实时显示在LCD屏幕上
注意点:LabView中输入的字符串的长度最好不要大于定义的字符数组