mv01--stc8a8k 串口互相发送接收(正常使用)

23 篇文章 0 订阅

mv–115200
8a8k—串口3,P00-rxd3,P01txd3— mv连接
8a8k–串口1电脑串口助手,调试。

8a8k发送 ReccmdA给openmv,
mv收到之后,进行判断,然后

mv端代码先发送
LED=0#,
再发送angle-x=1.3#给8a8k。

8a8k串口3收到数据,判断LED=0,再提取数据(在超时之内),将数据发送给mv,print出来,同时串口1发给串口助手,打印出来。测试数据是不是正常。

mv端代码

# Untitled - By: Administrator - 周四 四月 7 2022

import sensor, image, time
from pyb import UART
from pyb import Pin, Timer, LED

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)

#uart=UART(1,9600)  #PA9 txd   PA10--rxd 微翻weact 版OPENMV

uart = UART(3, 115200)  #正式openmv
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters timeout_char=1000

clock = time.clock()


g_uart_cmdA_flag=0   # 将变量声明为全局变量,如此才可改变其数值
g_uart_cmdB_flag=0

def Uart_recv():  # 串口接收数据
    global g_uart_cmdA_flag
    global g_uart_cmdB_flag

    if (uart.any()):   # 更新串口接收数据
        recv_data = eval(str(uart.read()))
        print(recv_data)
        #uart.write(recv_data)
        if ("Rec" in recv_data) :
            print("Openmv has recved CMD data.")
            if ("cmdA" in recv_data):
                g_uart_cmdA_flag = 1
                print("Ready for cmdA !")

            if ("cmdB" in recv_data):
                g_uart_cmdB_flag = 1
                print("Ready for cmdB !")

#--------------------------------定时器部分 start
is_need_send_data=False

def uart_time_tick(timer):
    global is_need_send_data
  #  uart.write("tick = true ^^^^^^\r\n ")
    is_need_send_data=True


##5ms读取一次检测一次串口,t=5ms f=1/t=200hz
tim = Timer(4, freq=5)      # create a timer object using timer 2 - trigger at 100Hz
tim.callback(uart_time_tick)          # set the callback to our tick function
#--------------------------------定时器结束

angle_x =10.2
xmm=896

#--------------------------------

while(True):
    clock.tick()
    if  is_need_send_data==False:
        continue    #注意continue用法,退出当前的循环一次,不执行后面的语句
    if is_need_send_data==True:
        is_need_send_data =False
       # uart.write("is_need_send_data = False *******\r\n ")
        Uart_recv()
        #time.sleep(500)
        img = sensor.snapshot()
        if g_uart_cmdA_flag ==1  :
           # uart.write("loc"+(str)adata+"num"+(str)bdata+"#")   # 串口发送
           # time.sleep(1000)
            uart.write("LED=0#")
            time.sleep(2)
            uart.write("angle_x=%0.2f#"%(angle_x))
            angle_x=angle_x+1.2
            if angle_x>2000:
                angle_x=10.2
            g_uart_cmdA_flag = 0

        if g_uart_cmdB_flag ==1  :
            #time.sleep(1000)
            uart.write("LED=1#")
            uart.write("xmm=%d#"%(xmm))
            g_uart_cmdB_flag = 0

8a8k端代码 22.1184M,115200波特率,定时器2和定时器3都被用了



//@22.1184M,stc8a8k
#include <stc8a8k.h>
#include <LCD12864B.h>
#include <delay.h>

#include <stdio.h>  
#include "stdlib.h"
#include "stdarg.h"
#include "string.h" 
//****************************************************************
bit Global_Uart3_busy; 
#define Uart3_Rec_Maxlength   100
unsigned char Global_Uart3_Rec[Uart3_Rec_Maxlength];//串口1接收空间,100个字节

#define Uart3_END_CODE     '#'  //帧尾自定义符号
unsigned char	Uart3_Rec_Byte_Length=0;//动态长度,在0-最大Uart1_Rec_Maxlength=100之间 0-255
unsigned char	Uart3_Rec_Frame_Flag=0;//接收一帧标记,=1,接收到一帧数据,=0,没有接受一帧数据

unsigned char Global_uart3cmdnum=0;//串口接收到的命令号
#define Uart3CMD_NULL  0 //串口接收到的命令
#define Uart3CMD_LED0  1 //串口接收到的命令
#define Uart3CMD_LED1  2 //串口接收到的命令
#define Uart3CMD_LED2  3 //串口接收到的命令

char uart3_print_buff[50];//串口3的打印缓冲,利用sprintf函数,将数据变为字符串,然后,可以用字符串打印函数打印出来
//例子:sprintf(uart3_print_buff,"%f",fdata)
//************************
void Uart3_Init(void);		//115200bps@22.1184MHz
void UART3_SendData(char dat);
void Uart3SendStr(char *p);
void Clear_Uart3_Rxbuff(void);
unsigned char  Judge_Uart3_Response(char* fmt,...);

unsigned char  Get_Uart3_AngleData(float *input_angle);
unsigned char  Get_Uart3_Int_Data(int *input_data);
unsigned char  Get_Uart3_Many(int input_data[]);


void Uart1_Init(void);		//115200bps@22.1184Mhz
void UartSendStr(char *p);
void UART1_SendData(char dat);
//void Clear_Uart1_Rxbuff(void);
//unsigned char  Judge_Uart1_Response(char* fmt,...);



void PortMode()
{
	P0M0=0x00;P0M1=0x00;
	P1M0=0x00;P1M1=0x00;
	P2M0=0x00;P2M1=0x00;
	P3M0=0x00;P3M1=0x00;
	P4M0=0x00;P4M1=0x00;
	P5M0=0x00;P5M1=0x00;
	P6M0=0x00;P6M1=0x00;
	P7M0=0x00;P7M1=0x00;

}
//*******************************主函数************************
//参考ISP软件,stc8a8k案例代码,定时器3做串口3波特率发生器串口3,波特率115200,定时器3产生,stc8a8k,22.1184Mhz
int main()
{	
	float angle_x=12.45;
	int xmm;
	int input_dataRec[3];
	int i;
	
	PortMode();//全部设置成准双向口模式,虽然默认是准双向口,但是为了稳妥,自己设置一次。
	Uart1_Init();//串口1,115200
	Uart3_Init();//串口3,波特率115200,定时器3产生,stc8a8k,22.1184Mhz p00-rxd3  p01--txd3
  IE2 = 0x08;
	ES=1;
  EA = 1;
	
	delay_ms(1000);
	
  printf("Uart3 Test !\r\n");
	
	sprintf(uart3_print_buff,"%.2f",angle_x);
	printf("Uart3 angle_x=");
  printf(uart3_print_buff);
	printf("\r\n");

  while(1)
  {
		Uart3SendStr("ReccmdA");
		delay_ms(5);
		if(Global_uart3cmdnum==Uart3CMD_LED0)  //获取浮点数
		{
			Global_uart3cmdnum=Uart3CMD_NULL;//清空命令,防止重复响应
		  printf("Uart3CMD_LED0 Test !\r\n");

			i=0;
			while(!Get_Uart3_AngleData(&angle_x))//	//电脑发过来的格式 angle_x=数据,超时监控
			{
				delay_ms(5);
				i++;
				if(i>3000)return 0;//超时监控
			}
			angle_x=angle_x+100;
			//将数据发送给openmv,调试用,在终端看到信息
		 	sprintf(uart3_print_buff,"%.2f",angle_x);
			Uart3SendStr("Uart3 angle_x=");
			Uart3SendStr(uart3_print_buff);
			Uart3SendStr("\r\n");
			//将数据发送给串口1,c调试用
			printf("angle =%0.2f\r\n",angle_x);
		}
		
		else if(Global_uart3cmdnum==Uart3CMD_LED1)//超时监控
		{
			printf("Uart3CMD_LED111Test !\r\n");
			Global_uart3cmdnum=Uart3CMD_NULL;//清空命令,防止重复响应
			i=0;
			while(! Get_Uart3_Int_Data(&xmm))//电脑发过来的格式 xmm=数据 ,超时监控
			{
				delay_ms(5);
				i++;
				if(i>3000)return 0;//超时监控
			}
			xmm=xmm+100;
			sprintf(uart3_print_buff,"%d",xmm);
			printf("Uart3 xmm=");
			printf(uart3_print_buff);
			printf("\r\n");
		}
		
		else if(Global_uart3cmdnum==Uart3CMD_LED2)
		{
			printf("Uart3CMD_LED333 Test !\r\n");
			Global_uart3cmdnum=Uart3CMD_NULL;//清空命令,防止重复响应
	
			i=0;
			while(!Get_Uart3_Many(input_dataRec))//电脑发过来的格式lr:数据,ud:数据,an:数据,超时监控
			{
				delay_ms(5);
				i++;
				if(i>3000)return 0;//超时监控
			}	
			
			sprintf(uart3_print_buff,"%d",input_dataRec[0]);
			printf("Uart3 xmm=");
			printf(uart3_print_buff);
			printf("\r\n");
			
			sprintf(uart3_print_buff,"%d",input_dataRec[1]);
			printf("Uart3 xmm=");
			printf(uart3_print_buff);
			printf("\r\n");
			
			sprintf(uart3_print_buff,"%d",input_dataRec[2]);
			printf("Uart3 xmm=");
			printf(uart3_print_buff);
			printf("\r\n");
			
					delay_ms(500);

		}
	}
}

//串口3,波特率115200,定时器3产生,P00--RXD3  P01--TXD3
void Uart3_Init(void)		//115200bps@22.1184Mhz
{
	Global_Uart3_busy=0;
	S3CON = 0x10;		//8位数据,可变波特率
	S3CON |= 0x40;		//串口3选择定时器3为波特率发生器
	T4T3M &= 0xFD;		//定时器3时钟为Fosc/12,即12T
	T3L = 0xFC;		//设定定时初值
	T3H = 0xFF;		//设定定时初值
	T4T3M |= 0x08;		//启动定时器3
}

//UART3 发送串口数据,一个字节
void UART3_SendData(char dat)
{
    while (Global_Uart3_busy);
    Global_Uart3_busy = 1;
    S3BUF = dat;
}
//UART3 发送串口数据,字符串
void Uart3SendStr(char *p)
{
    while (*p)
    {
        UART3_SendData(*p++);
    }
}


//串口3中断服务函数
void Uart3Isr() interrupt 17 using 1
{
    if(S3CON & 0x02)
    {
      S3CON &= ~0x02; //清零发送标记位
			Global_Uart3_busy=0;
    }
    if (S3CON & 0x01)
    {
      S3CON &= ~0x01;//清零接收标记位
			Global_Uart3_Rec[Uart3_Rec_Byte_Length]=S3BUF;//将数据放到缓冲区中
			if(Global_Uart3_Rec[Uart3_Rec_Byte_Length]==Uart3_END_CODE) //如果接收到的最后的数据是约定好的帧尾
			{
				Uart3_Rec_Byte_Length=0;//接收标记等于1,在哪里清0?在判断里面清0
				Uart3_Rec_Frame_Flag=1;//长度清零,给下次使用
				//判断命令,得到串口命令
				if(Judge_Uart3_Response("LED=0"))//如果一帧数据里面包括了LED=0
				{
					Clear_Uart3_Rxbuff(); //清空空间,下次接收
					Global_uart3cmdnum = Uart3CMD_LED0;
				}			
				else 	if(Judge_Uart3_Response("LED=1"))//如果一帧数据里面包括了LED=0
				{
					Clear_Uart3_Rxbuff(); //清空空间,下次接收
					Global_uart3cmdnum = Uart3CMD_LED1 ;
				}
				else 	if(Judge_Uart3_Response("LED=2"))//如果一帧数据里面包括了LED=0
				{
					Clear_Uart3_Rxbuff(); //清空空间,下次接收
					Global_uart3cmdnum = Uart3CMD_LED2 ;
				}
				
			}
			else
			{
			  Uart3_Rec_Byte_Length++;//递增,不断放到数组中
			  if(Uart3_Rec_Byte_Length>Uart3_Rec_Maxlength-1) Uart3_Rec_Byte_Length=0;
		  }	
    }
}

//清除串口3的内存
void Clear_Uart3_Rxbuff(void)
{
	unsigned char *p,i;
	p=Global_Uart3_Rec;
	for(i=0;i<Uart3_Rec_Maxlength;i++)
	{
		*p++=0;
	}
	Uart3_Rec_Byte_Length=0;
	Uart3_Rec_Frame_Flag=0;
}
//判断命令,这里注意,必须全部包括
unsigned char Judge_Uart3_Response(char* fmt,...)
{	
	va_list ap;
	char p[30];
	if(!Uart3_Rec_Frame_Flag) return 0;

	va_start(ap,fmt);
	vsprintf((char*)p,fmt,ap);
	va_end(ap); 
	if(strstr((char*)Global_Uart3_Rec,p)==NULL) return 0;
	else return 1;
}

//实例,获取串口传来的角度,angle=325.56
unsigned char Get_Uart3_AngleData(float *input_angle)
{
	float angletemp;
	if(!Uart3_Rec_Frame_Flag) return 0;
	sscanf((const char *)Global_Uart3_Rec,"angle_x=%f",&angletemp);//angle=325.56
	*input_angle=(float)angletemp;
	return 1;
}
//实例,获取串口3传来的整数,intdata=13568
unsigned char Get_Uart3_Int_Data(int *input_data)
{
	int inttemp;
	if(!Uart3_Rec_Frame_Flag) return 0;
	sscanf((const char *)Global_Uart3_Rec,"xmm=%d",&inttemp);//xmm=8756
	*input_data=(float)inttemp;
	return 1;
}
//串口3接收一系列,截取出来数据lr:%d,ud:%d,an:%d
unsigned char  Get_Uart3_Many(int input_data[])
{
	int input_dataTemp[3];
	if(!Uart3_Rec_Frame_Flag) return 0;
	sscanf((const char *)Global_Uart3_Rec,"lr:%d,ud:%d,an:%d",&input_dataTemp[0],&input_dataTemp[1],&input_dataTemp[2]);
	input_data[0]=input_dataTemp[0];
	input_data[1]=input_dataTemp[1];
	input_data[2]=input_dataTemp[2];
	return 1;
}

//UART1 发送串口数据,一个字节
void UART1_SendData(char dat)
 {
     ES=0;           //关串口中断
     SBUF=dat;           
     while(TI!=1);   //等待发送成功
     TI=0;           //清除发送中断标志
     ES=1;           //开串口中断
}
//UART1 发送串口数据,字符串
void UartSendStr(char *p)
{
    while (*p)
    {
        UART1_SendData(*p++);
    }
}
//重写putchar函数,可以用printf函数
char putchar(char c)
{
     UART1_SendData(c);
     return c;
}
//串口1,波特率115200,定时器2产生,
void Uart1_Init(void)		//115200bps@22.1184Mhz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
	T2L = 0xFC;		//设定定时初值
	T2H = 0xFF;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值