通信的基本概念
1.串行与并行通信
![](https://i-blog.csdnimg.cn/blog_migrate/14fa91a781c7d4884d6f4647ace57f7f.png)
串行通讯:USRAT,IIC,SPI
![](https://i-blog.csdnimg.cn/blog_migrate/fe89a2742540367f22db796a037e8370.png)
2.全双工、半双工和单工
iic是单工的
3.同步与异步
有有时钟信号的都叫同步,没有时钟信号的都叫异步
4.通信的速率
比特率:是指每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,每秒传送数据就越多。
波特率:表示每秒钟传送码元符号的个数,是衡量数据传送速率的指标。
在信息传输通道中,携带数据信息的信号单元叫码元,每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。波特率是传输通道频宽的指标。
传输速率:传输速率是一种泛指,指的是数据从一点向另一点传输的速率。包含上面的比特率、波特率等。
通信速度:通信速度和传速速度同样也是一种泛指。比如I2C通信速度100KHz,SPI最大通信速度支持150Mbps。
串口通信----串口通信协议简介
串口功能框图讲解
IE:中断使能。
USART_CR1:UE,TE.RE
TXE:发送缓冲区
RXE接收缓冲区
这里DIV_Mantissa=39=0x27
USART_BRR=0X271
STM32串口初始化结构体固件库
25.6.1 状态寄存器(USART_SR)
USART1发送数据
#ifndef __USART1_H
#define __USART1_H
#include "stm32f10x.h"
//
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxCLKCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
//
#define DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
//
#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler
void USART_Config(void);
void Usart_SendByte( USART_TypeDef* PUSARTx ,uint8_t data);
#endif
#include "usart1.h"
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_APB2PeriphClockCmd(DEBUG_USART_CLK|DEBUG_USART_GPIO_CLK, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; //PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; //串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
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(DEBUG_USARTx, &USART_InitStructure); //初始化串口1
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(DEBUG_USARTx, ENABLE); //使能串口1
}
void Usart_SendByte( USART_TypeDef* PUSARTx ,uint8_t data)
{
USART_SendData( PUSARTx, data);
while( USART_GetFlagStatus( PUSARTx, USART_FLAG_TXE ) == RESET);
}
记得不记得拍死!!
串口发送和接收字节讲解
/*发送两个字节的数据*/
void Usart_SendHalfWord( USART_TypeDef* PUSARTx ,uint16_t data)
{
uint8_t temp_h,temp_l;
temp_h = (data&0xff00) >> 8 ; //要发送的高八位数据
temp_l = (data&0xff); //要发送的低八位数据
USART_SendData( PUSARTx, temp_h); //USART1要发送的数据data
while( USART_GetFlagStatus( PUSARTx, USART_FLAG_TXE ) == RESET);//当数据已经转移到位移寄存器,然后输出到上位机
USART_SendData( PUSARTx, temp_l); //USART1要发送的数据data
while( USART_GetFlagStatus( PUSARTx, USART_FLAG_TXE ) == RESET);//当数据已经转移到位移寄存器,然后输出到上位机
}
//发送8位数据的数组
void Usart_SendArr( USART_TypeDef* PUSARTx ,uint8_t *arr ,uint8_t num)
{
uint8_t i;
for( i=0;i<num;i++ )
{
Usart_SendByte( PUSARTx ,arr[i]);
}
while( USART_GetFlagStatus( PUSARTx, USART_FLAG_TC ) == RESET);//TC:发送完成 (Transmission complete)
}
int main(void)
{
uint8_t a[10]={1,2,3,4,5,6,7,8,9,10};
USART_Config();
Usart_SendArr( DEBUG_USARTx ,a ,10) ;
while(1) {}
}
代码解析:
uint8_t *arr arr是存放地址的指针变量 (数组、字符) 传入的参数可以是地址 :a a[10]
发送字符串:
/*发送一个字符串*/
void Usart_SendStr( USART_TypeDef* PUSARTx ,uint8_t *str )
{
uint8_t i=0; //注意i要初始化,不初始化指针里的地址飞到哪里去了
do
{
Usart_SendByte( PUSARTx , *(str+i));
i++;
}while(*(str+i) !='\0');
while( USART_GetFlagStatus( PUSARTx, USART_FLAG_TC ) == RESET);//TC:发送完成 (Transmission complete)
}
在keil使用printf
/*使用microLib的方法*/
/*
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}
return ch;
}
int main(void)
{
uint8_t a[10]={1,2,3,4,5,6,7,8,9,10};
USART_Config();
// Usart_SendByte( DEBUG_USARTx , 'A');
// Usart_SendHalfWord( DEBUG_USARTx ,0xff56);
Usart_SendArr( DEBUG_USARTx ,a ,10) ;
while(1)
{
}
}
程序移植!!
#ifndef __USART1_H
#define __USART1_H
#include "stm32f10x.h"
#include "stdio.h"
#define DEBUG_USART1 0
#define DEBUG_USART2 0
#define DEBUG_USART3 1
//
#if DEBUG_USART1
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxCLKCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
//
#define DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
//
#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler
#elif DEBUG_USART2
//串口2
#define DEBUG_USARTx USART2
#define DEBUG_USART_CLK RCC_APB1Periph_USART2
#define DEBUG_USART_APBxCLKCmd RCC_APB1PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
//
#define DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_2
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_3
//
#define DEBUG_USART_IRQ USART2_IRQn
#define DEBUG_USART_IRQHandler USART2_IRQHandler
#elif DEBUG_USART3
//串口3
#define DEBUG_USARTx USART3
#define DEBUG_USART_CLK RCC_APB1Periph_USART3
#define DEBUG_USART_APBxCLKCmd RCC_APB1PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
//
#define DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOB
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//
#define DEBUG_USART_TX_GPIO_PORT GPIOB
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_10
#define DEBUG_USART_RX_GPIO_PORT GPIOB
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_11
//
#define DEBUG_USART_IRQ USART3_IRQn
#define DEBUG_USART_IRQHandler USART3_IRQHandler
#endif
void USART_Config(void);
void Usart_SendByte( USART_TypeDef* PUSARTx ,uint8_t data);
void Usart_SendHalfWord( USART_TypeDef* PUSARTx ,uint16_t data);
void Usart_SendArr( USART_TypeDef* PUSARTx ,uint8_t *arr ,uint8_t num);
void Usart_SendStr( USART_TypeDef* PUSARTx ,uint8_t *str);
#endif
发送数据给上位机~_~
在stm32f10x_it.c需要添加#include "usart1.h"
void DEBUG_USART_IRQHandler(void)
{
uint8_t ucTemp;
if( USART_GetFlagStatus( USART1, USART_FLAG_RXNE )!=RESET )
{
ucTemp= USART_ReceiveData(USART1);
USART_SendData(USART1, ucTemp);
}
}