/*********************************************************************************************/
串口数据帧发送格式:1个起始位 + 8个数据位 + 1个停止位
思路:1.PA9做普通IO推挽输出,按照发送格式用延时暂时作为该位的传输时间,波特率为9600
2.PA10做浮空输入,外部共享中断使用(可用其余外部中断),每接收到一个数据就进中断一次,循环接收判断,当接收到\r\n将接收标志置为0x8000(或为1);
********************************************************************************************/
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
void SendOneByte(u8 Byte);
SendOneByte((uint8_t) ch);
return ch;
}
#endif
//发送一个字节数据
void SendOneByte(u8 Byte)
{
u8 i=8,tmp;
TXD_low(); //发送起始位
delay_us(104);
//发送8位数据
for(i=0;i<8;i++)
{
tmp = (Byte >> i) & 0x01; //低位在前
if(tmp == 0)
{
TXD_low();
delay_us(104); //0
}
else
{
TXD_high();
delay_us(104); //1
}
}
TXD_high();//发送停止位
delay_us(104);
}
//发送数组最好用这个,也可发送字符串
void SendBytes(u8 *str,u8 len)
{
u16 i;
for(i=0;i<len;i++)
{
SendOneByte(str[i]);
}
}
void SendStr(u8 *str) //发送字符串,发送数组如果带0x00就中断发送了
{
while(*str)
SendOneByte(*str++);
}
int main(void)
{
u8 len;
u8 hello[]={0x5a,0xa5,0x00,0x00,0x01};
delay_init();
EXTIX_Init();
//测试 发送一个字节
SendOneByte(0x00);
SendOneByte(0x01);
SendOneByte(0x02);
//测试发送数组
SendBytes(hello,5);
while(1)
{
if(USART_RX_STA&0x8000)
{
printf("\r\n您发送的消息为:\r\n\r\n");
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
SendBytes(USART_RX_BUF,len);
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}
}
}
/****************************************************************************************/
u8 tmp; //接收的数据(数据中间转换)
u8 USART_RX_BUF[USART_REC_LEN];//接收缓冲区
u16 USART_RX_STA=0; //接收完成标志
//extern SendOneByte(u8 Byte);
//外部中断初始化
void EXTIX_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 端口配置 -- TX发送端
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.9
GPIO_SetBits(GPIOA,GPIO_Pin_9);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.10 端口配置 -- RX接收端
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_10);
//GPIOA.10 中断线以及中断初始化配置 下降沿触发
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource10);
EXTI_InitStructure.EXTI_Line=EXTI_Line10;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//浮空输入
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //中断号
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //中断使能
NVIC_Init(&NVIC_InitStructure);
}
/*共享中断接收函数*/
void EXTI15_10_IRQHandler(void)
{
u8 i=9;
if(EXTI_GetITStatus(EXTI_Line10) != RESET)
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->ICER[EXTI15_10_IRQn >> 0x05] = (uint32_t)0x01 << (EXTI15_10_IRQn & (uint8_t)0x1F);
EXTI_ClearITPendingBit(EXTI_Line10);//清除中断标志
delay_us(30);
while(i--)//10个数据 1byete起始位+8byte数据位+1byte停止位
{
tmp >>=1; //移位
if(GPIOA->IDR&0x0400) tmp |=0x80;//PA10接收到的数据为1
delay_us(104);
}
if((USART_RX_STA&0x8000)==0)//接收标志为0
{
if(USART_RX_STA&0x4000)
{
if(tmp!=0x0a) USART_RX_STA=0;//未接收到\n,标志清0 '\n' == 0x0a
else USART_RX_STA |=0x8000; //接收结束,标志置0x8000
}
else
{
if(tmp==0x0d) USART_RX_STA|=0x4000;//接收到结束标志\r,表示接收可能快结束 '\r' == 0x0d
else //未接收完成,接收数据缓存到缓冲区
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=tmp ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
EXTI_ClearITPendingBit(EXTI_Line10);
NVIC->ISER[EXTI15_10_IRQn >> 0x05] =
(uint32_t)0x01 << (EXTI15_10_IRQn & (uint8_t)0x1F);
}
}
串口TX测试结果:(上电后发送)
串口RX测试结果:(发送的数据回传)
作者:广东松山电子实验室
+WeChat(linzebinwinner)