学习记录(4)

一、串口通信原理

并行通信

  • 数据同时传输
  • 速度快,但占用引脚多

串行通信

  • 数据按位传输
  • 速度慢,但占用引脚少
    按照数据传输方向,可分为:
    单工:数据传输只支持数据在一个方向上传输。
    半双工:允许数据在两个方向上传输,但是在某一时刻只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;
    全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备接收设备都有独立的接收和发送能力。

通信方式

  • 同步通信
  • 异步通信

常见的串行通信接口

在这里插入图片描述

STM32的串口通信接口

  • UART:通用异步收发器
  • USART:通用同步异步收发器

UART异步通信方式特点

异步通信方式引脚:

  • RXD:数据输入引脚:数据接受;
  • TXD:数据发送引脚:数据发送。

在这里插入图片描述
关于波特率的计算:
在这里插入图片描述

串口通信过程

  • 数据接收过程:外部设备按照一定的波特率将数据传送到串行输入移位寄存器,串行输入移位寄存器将所接收到的数据一次性传入到输入数据缓存器,之后再将数据传送到MCU。
  • 数据发送过程:与数据接收过程相反。

串口异步通信需要定义的参数

常用寄存器和库函数

在这里插入图片描述

串口设置的一般步骤可以总结为如下几个步骤:

  1. 串口时钟使能,GPIO 时钟使能
  2. 串口复位
  3. GPIO 端口模式设置
  4. 串口参数初始化
  5. 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
  6. 使能串口
  7. 编写中断处理函数
    代码实现如下:
void MY_USART1_Init(void)
 {
	 GPIO_InitTypeDef GPIO_InitStrue;
	 USART_InitTypeDef USART_InitStrue;
	 NVIC_InitTypeDef NVIC_InitStrue;
	 
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口时钟使能
	 
	 
	 GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;  //复用推挽输出
	 GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
	 GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
	   GPIO_Init(GPIOA,&GPIO_InitStrue);

	 GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;  //浮空输入
	 GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
	 GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
	   GPIO_Init(GPIOA,&GPIO_InitStrue);             //GPIO端口初始化
	 
	 
	 USART_InitStrue.USART_BaudRate=115200;         //波特率设置
	 USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //无硬件数据流控制
	 USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;  //设置收发模式
	 USART_InitStrue.USART_Parity=USART_Parity_No;  //无奇偶校验位
	 USART_InitStrue.USART_StopBits=USART_StopBits_1;  //停止位设置为1
	 USART_InitStrue.USART_WordLength=USART_WordLength_8b; // 字长设置为8位
	 
	 USART_Init(USART1,&USART_InitStrue);   //串口初始化
	 
	 USART_Cmd(USART1,ENABLE);//使能串口
	 
	 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启接收中断,开启中断服务函数,设置中断类型
	 
	 NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;
	 NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;    //通道使能
	 NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级1
	 NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;   //子优先级1
	 NVIC_Init(&NVIC_InitStrue);    //中断优先级初始化
 }

void USART1_IRQHandler(void)函数

void USART1_IRQHandler(void)函数是串口 1 的中断响应函数,当串口 1 发生了相应的中断后,就会跳到该函数执行。中断相应函数的名字是不能随便定义的,一般我们都遵循MDK定义的函数名。这些函数名字在启动文startup_stm32f10x_hd.s文件中可以找到。
函数体里面通过函数:

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 

判断是否接受中断,如果是串口接受中断,则读取串口接受到的数据:

Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据

读到数据后接下来就对数据进行分析。
通过这个函数 , 配合一个数组USART_RX_BUF[],一个接收状态寄存器 USART_RX_STA(此寄存器其实就是一个全局变量,由作者自行添加。由于它起到类似寄存器的功能,这里暂且称之为寄存器)实现对串口数据的接收管理。USART_RX_BUF 的大小由 USART_REC_LEN 定义,也就是一次接收的数据最大不能超过 USART_REC_LEN 个字节。USART_RX_STA 是一个接收状态寄存器其各的定义如下:
在这里插入图片描述

设计思路如下:
当接收到从电脑发过来的数据,把接收到的数据保存在 USART_RX_BUF 中,同时在接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(回车的表示由 2 个字节组成:0X0D 和 0X0A)的第一个字节 0X0D 时,计数器将不再增加,等待0X0A 的到来,而如果 0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如果顺利接收到 0X0A,则标记 USART_RX_STA 的第 15 位,这样完成一次接收,并等待该位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到 0X0D,那么在接收数据超过 USART_REC_LEN 的时候,则会丢弃前面的数据,重新接收。

printf函数

通过 printf 函数向串口发送我们需要的内容,方便开发过程中查看代码执行情况以及一些变量值。
以下是正点提供的一段代码:

 int main(void)
 {	
	u8 t;
	u8 len;	
	u16 times=0; 
 
	delay_init();	    	 //延时函数初始化	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	uart_init(9600);	 //串口初始化为9600
	LED_Init();		  	 //初始化与LED连接的硬件接口 
 
	while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n");
			for(t=0;t<len;t++)
			{
				USART1->DR=USART_RX_BUF[t];
				while((USART1->SR&0X40)==0);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("\r\nALIENTEK MiniSTM32开发板 串口实验\r\n");
				printf("正点原子@ALIENTEK\r\n\r\n\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}
	}	 
}



二、外部中断

外部中断相关知识:
STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103的 19 个外部中断为:

线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。

中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。
在这里插入图片描述

typedef struct
{
 uint32_t EXTI_Line; //指定要配置的中短线
 EXTIMode_TypeDef EXTI_Mode; //模式:事件OR中断
 EXTITrigger_TypeDef EXTI_Trigger; //触发方式:上升沿,下降沿,双触发沿
 FunctionalState EXTI_LineCmd; //使能OR中断
}EXTI_InitTypeDef;

使用 IO 口外部中断的一般步骤:
1)初始化 IO 口为输入。
2)开启 IO 口复用时钟AFIO,设置 IO 口与中断线的映射关系。
3)初始化线上中断,设置触发条件等。
4)配置中断分组(NVIC),并使能中断。
5)编写中断服务函数
6) 清除中断标志位
下面通过一段代码来展示以上步骤:

//外部中断初始化函数
void EXTIX_Init(void)
{
  EXTI_InitTypeDef EXTI_InitStrue;
	NVIC_InitTypeDef NVIC_InitStrue;
	
 	 KEY_Init();//初始化IO口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启IO口复用时钟,AFIO
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);//设置IO口与中断线的映射关系
	
	EXTI_InitStrue.EXTI_Line=EXTI_Line5;//指定要配置的中断线
	EXTI_InitStrue.EXTI_LineCmd=ENABLE;
	EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;//设置中断触发模式
	EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿
	EXTI_Init(&EXTI_InitStrue);
	
	NVIC_InitStrue.NVIC_IRQChannel=EXTI9_5_IRQn;//使能按键所在的外部中断通道
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=2;//设置子优先级
	NVIC_Init(&NVIC_InitStrue);
//KEY0中断服务函数初始化
 
  	
}

void EXTI9_5_IRQHandler(void)
{
    delay_ms(10);//消抖
	  if(KEY0==0)
      {
          LED0=!LED0;
				 // LED1=!LED1;
      }
		EXTI_ClearITPendingBit(EXTI_Line5);//清除Line5上的中断标志位
}


三、使用keil 5编译过程中遇到的问题汇总

warning:#1-D:last line of file ends without a new line

一般情况下,写完代码之后,在程序末尾需要点击回车键才会消除警告;但有的时候明明已经按了回车键,但还是会报错。此时的解决办法是:将光标移至出错的程序末尾,按住delete键,直至确认后面没有空格,之后再点击回车,此时光标会移至下一行,要特别注意的是,光标一定要在空白行的最前端,然后警告才会消失。

Undefined symbol TIM_Int_Init (referred from main .o)

解决办法:
在这里插入图片描述
3.当project window找不到时,像这样:
在这里插入图片描述
可以采取下面的办法:
在这里插入图片描述
将view中的project window 选中即可。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我会为您提供关于 MSP430F5529 的 ADC12 学习笔记。 MSP430F5529 是德州仪器(Texas Instruments)公司推出的一款低功耗微控制器,它具有 12 位的模数转换器(ADC12)模块,可以用于采集模拟信号。 ADC12 模块具有多个配置选项和功能,下面是一些相关的学习笔记: 1. ADC12 基本配置:首先,您需要对 ADC12 进行基本的配置。这包括选择参考电压源、设置采样保持时间、选择转换时钟源等。可以通过配置控制寄存器(ADC12CTL0 和 ADC12CTL1)来完成这些设置。 2. 通道选择:ADC12 可以选择多个输入通道进行采样。您可以使用 ADC12MCTLx 寄存器来选择所需的输入通道,并进行相关的配置,如参考电压源、输入通道的输入方式(单端或差分)等。 3. 触发方式:ADC12 可以通过软件触发或外部触发进行转换。您可以使用 ADC12CTL0 寄存器来选择触发方式,并设置相应的触发源。 4. 转换结果:ADC12 转换后的结果可以通过 ADC12MEMx 寄存器进行读取。对于 12 位的转换结果,您可以直接读取 ADC12MEMx 寄存器的值。 5. 中断和DMA:ADC12 可以使用中断或 DMA 来处理转换完成后的结果。通过配置 ADC12CTL0、ADC12CTL1 和相关中断/ DMA 控制寄存器,您可以实现转换完成后的中断或 DMA 传输。 请注意,上述仅为一些基本的学习笔记,MSP430F5529 的 ADC12 模块还有更多高级功能和配置选项。您可以参考 MSP430F5529 的用户手册和相关文档,以深入了解 ADC12 模块的更多细节和应用。 希望这些笔记能对您有所帮助!如果您对其他问题感兴趣,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值