1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、数据的传送方式 1.串行通信 速度慢,但占用资源少,按顺序传输、逐个位传输,(使用一个数据线就能解决传输问题,即一个I/O口就可以解决问题) 2.并行通信 速度快,但占用资源多,各个位同时传输、多位传输,(多少位数据就需要多少根数据线) 适用于:USART,IIC,SPI 二、数据的通信方式 1、单工通信 iic,spi A发--单向通道--B收 2、半双工通信 spi A发--双向通道--B收 / B发--双向通道--A收 (同一时刻时,一个设备发送时,另一个就不能同时进行发送) 3、全双工通信 usart,spi A发、B发--双向通道--B收、A收 (两个设备在同一时刻都可以进行收发数据,传输) 三、数据的同步方式 【同步 & 异步】 1、同步通信 ①数据传送以数据块(多个字符组成的)的形式的;在数据块内,字符与字符间无间隔 ②接收与发送时钟严格同步,有同步时钟SCLK ③通信双方的各自的两个时钟SCLK是连在一起的,提供同步时钟;接受与发送是同步的 2、异步通信 ①没有时钟线SCLK的约束,因此有了② ②在发送数据之前发送一个起始位, 发送奇偶检验位+想要发送的字符,最后发送停止位 比较 有无时钟SCLK的约束 四、数据的通信速率 1、比特率(在IIC,SPI中使用)Bitrate 每秒传输的二进制位,bit/s 2、波特率(在串口中使用)Baudrate 每秒传输的码元个数 一个二进制位表示一个码元 五、串口通信 TTL电平:数字芯片的电平,单片机使用,0-5V 232电平:电脑串口的电平,工业电平,-3-15V 原生串口通信:直接设备与传感器连接 (eg. GPS模块,WiFi模块...) 1、串口数据包的基本组成 起始位:逻辑0 (第一个低电平) 停止位:逻辑0.5/1/1.5 (高电平) 可以达到校准同步时钟的目的 有效数据位: 校验位: 校验方法有: 奇校验:有效数据+校验位中的“1”个数为奇数; 即如:10010110,有四个1了,校验位加上一个1,凑5个,为奇校验 (九个位传输) 偶校验:有效数据+校验位中的“1”个数为偶数; 即如:10010110,有四个1了,校验位加上一个0,不加1保持4个1不变,为偶校验 (九个位传输) 0校验:校验位总为0 1校验:校验位总为1 无校验:数据不包含校验位 六、串口的结构体 1、串口通信 TX 发送(配置输出模式) RX 接收(配置输入模式,浮空输入) USART:同步异步收发器 UART :异步收发器 ↓ 在“中文参考手册” ↓ 可以看出 USART1在APB2总线下,其余在APB1总线下 APB2的频率与AHB系统总线的频率一样 (72*10的6次方 hz ) APB1 (32*10 6) 2、异步收发器的结构体的配置
波特率设置: (在APB2中是)使用固件库时直接设置 =115200 =72 *10(6次方)/16*USATDIV
有 8位 与 9位
正常情况下使用 1 停止位
USART_Mode_Rx | USART_Mode_Tx 即可 表示Rx输入Tx输出都可行
一般情况下,不做选择 3、同步收发器的结构体配置 uint16_t USART_Clock; //时钟配置 uint16_t USART_CPOL; //极性 配置串口空闲为什么电平 uint16_t USART_CPHA; //相位 配置选择边沿 1Edge 第一边沿 ≈ 上升沿 2Edge 第二边沿 ≈ 下降沿 uint16_t USART_LastBit; //配置最后一位时钟,使能开关 4、常用函数 七、配置串口的发送与接收
1、串口接收字符 1、打开APB2下的GPIOA的时钟信号;因为UART1在APB2总线下 2、同时使能引脚复用时钟 3、打开UART1的时钟信号 4、【配置APB2下的GPIOA的结构体】 配置PA9串口---TX线---输出引脚 Mode:推挽输出 5、【配置APB2下的GPIOA的结构体】 配置PA10串口---RX线---输入引脚(接收) Mode:浮空输入 记得初始化结构体 stm32f10x_gpio.h 6、【配置串口的结构体】 BaudRate=115200; Mode=USART_Mode_Rx | USART_Mode_Tx; 记得初始化结构体 + 使能串口 USART_Cmd() stm32f10x_uart.h #include "stm32f10x.h" #include "usart.h" void usart_demo(void) { GPIO_InitTypeDef GPIOinitStruct; USART_InitTypeDef USARTinitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //PA9 GPIOinitStruct.GPIO_Mode=GPIO_Mode_AF_PP; GPIOinitStruct.GPIO_Pin=GPIO_Pin_9; GPIOinitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIOinitStruct); //PA10 GPIOinitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIOinitStruct.GPIO_Pin=GPIO_Pin_10; GPIO_Init(GPIOA, &GPIOinitStruct); //串口配置 USARTinitStruct.USART_BaudRate=115200; USARTinitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USARTinitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx; USARTinitStruct.USART_Parity=USART_Parity_No; USARTinitStruct.USART_StopBits=USART_StopBits_1; USARTinitStruct.USART_WordLength=USART_WordLength_8b; USART_Init(USART1, &USARTinitStruct); USART_Cmd(USART1,ENABLE); } 2、主函数 int main() { USART_SendData(USART1, 'X');//发送字符函数 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//判断串口状态函数 USART_SendData(USART1, 'Y'); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); USART_SendData(USART1, 'n'); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); delay(1000); } USART_FLAG_TXE 发送空标志位定义;判断当串口的状态是空的时候,即字符发送完毕的时候;执行下一个字符的发送 3、串口接收字符串 在接收字符的基础上,封装2个函数,实现达到字符串输出的目的 封装一个输出单个字符的函数 void USART_SendByte(USART_TypeDef* USARTx, uint16_t data) { USART_SendData(USARTx, data); while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET); } 封装一个输出字符串的函数 void USART_SendStr(USART_TypeDef* USARTx, char *str)//字符串以指针的形成存入 { uint16_t i=0; do { USART_SendByte(USARTx, *(str + i)); //利用i++逐个通过字符函数进行输出 i++; } while(*(str + i) != ' |