串口:
实验平台:正点原子战舰开发板
系统:windows 7 64位
编译器:MDK 4.72a
参考例程:ATK串口例程,野火ISO串口例程
串口是一个重要的外设,基本就是芯片唯一对外输出的一种方式,其他点灯,按键什么的都是小case。
先简单介绍下串口的工作原理:
先看个内部结构图
备注:摘至野火零死角玩转STM32
不要看图很复杂,我也不具体讲一大堆的原理,文字这么长都看的头疼。我就简单说说:
发送和接受原理基本相同,都是设置好数据长度,校验位,停止位。然后把数据送到移位寄存器中,这时候硬件会根据时钟脉冲一位一位的把数据接受或者发出。。。这就是简单的原理
下面具体来说说用库函数是怎么实现的:
先来看看配置串口的步骤:
备注:摘自正点原子STM32开发指南
1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
凡是涉及到GPIO都要使能时钟。
2. 这个做不做都行,反正默认都是恢复缺省值,有需要时候调用
USART_DeInit (USARTx);
3. GPIO的设置就和流水灯的差不多
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
参考STM32中文手册配置即可:
要注意输出引脚要配置输出频率。
4. 串口初始化也基本都是格式化了。。可以改的也不多
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx| USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
第一个波特率
第二个数据长度
第三个停止位
第四个无奇偶校验
第四个硬流控不使用
第五个选择输入输出模式
最后初始化USART。
5. NVIC中断控制器后面会有专门介绍这里先给出代码
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
6. 使能串口没什么好说的
USART_Cmd(USART1, ENABLE);
7. 编写中断函数
void USART1_IRQHandler(void)
{
uint8_t ch;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
ch = USART_ReceiveData(USART1);
printf( "%c", ch );
}
}
最后重定向printf
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return (ch);
}
最后printf就可以输出了,也可以接收了。