当前位置:首页 > 资讯 > info5 > 正文

【菜鸟入门】stm32 之 USART

发表于: 2013-11-14   作者:ieczw   来源:转载   浏览:
摘要: 这是学习stm32的第四天了,怎么说呢?感触最大的是,细心最重要,为什么呢?昨天,一个二进制到十六进制换算出来问题,导致一个问题纠结了一下午,今天,在初始化时钟的时候,把9写成10,导致,串口到下午才调试好。好吧,现在开始说串口。在我的板子上,USART1对应的PIN是PA10---RXINPUT Mode:0x8PA9---TXOUTPUT Mode:0xb其实串口初始化也就分下面几步:(1)P

这是学习stm32的第四天了,怎么说呢?感触最大的是,细心最重要,为什么呢?昨天,一个二进制到十六进制换算出来问题,导致一个问题纠结了一下午,今天,在初始化时钟的时候,把9写成10,导致,串口到下午才调试好。

好吧,现在开始说串口。

在我的板子上,USART1对应的PIN是

PA10 --- RX INPUT   Mode:0x8
PA9 ---TX OUTPUT  Mode:0xb

其实串口初始化也就分下面几步:

(1)PIN管脚时钟使能,特殊功能寄存器使能,即GPIOA和USART1时钟使能;

(2)USART管脚配置,PA10配置成输入模式:0x8;PA9配置成输出模式;【前面讲过怎么配置】

(3)USART Reset;记得关闭Reset;

(4)USART 波特率设置;

(5)USART寄存器配置;

(6)USART中断配置;


还是老规矩,先附上代码:

/* USART0
		PA10 ---	RX INPUT  M:0x8
		PA9	 --- 	TX OUTPUT M:0xb
*/
#define CPU_RATE_72M	72

int rs232_init(u32 cpu_rate,u32 baud)
{
	float div;
	u16		div_int = 0;
	u16		div_float = 0;
	/* Get Div Baud */
	div = (float)(cpu_rate*1000000)/(16*baud);
	div_int = div;
	div_float = 16*(div - div_int);
	div_int <<= 4;
	div_int += div_float;
	
	RCC->APB2ENR |= 1<<2;
	RCC->APB2ENR |= 1<<14;
	
	GPIOA->CRH &= ~(0xff<<4);	//clear CRH at bit 10:9
	GPIOA->CRH |= 0x8b << 4;	//set CRH at bit 10:9
	
	RCC->APB2RSTR |= 1<<14;		//Reset USART0
	RCC->APB2RSTR &= ~(1<<14);//Stop Reset USART0
	
	/* config USART */
	USART1->BRR = div_int;	// Set Baud Rate

	USART1->CR1 &= ~(1<<12);			// Set Data bit :8bit
	USART1->CR1 &= ~(1<<10);			// CRC
	USART1->CR1 |= 1<<8;			// Enable PE Interrupt
	USART1->CR1 |= 1<<5;			// Enable RX Interrupt
	USART1->CR1 |= 3<<2;			//Enable RX TX
	USART1->CR2 &= ~(3<<12);	// Stop Bit :00 => 1SB
	USART1->CR1 |= 1<<13;			// Enable USART
	
	init_interrupt(2,37,3,3);
	return 0;
}

APB2ENR寄存器如下,我们要使能IOPA和USART1的时钟所以,APB2ENR |= (1<<2) | (1<<14)


APB2RSTR是外设复位寄存器:我们最好把USART1重新复位下,来确保系统的稳定性:

【菜鸟入门】stm32 之 USART_第1张图片

但是,在复位完成之后,一定要对该控制位置零,停止复位;

APB2RSTR |= 1<<14;

APB2RSTR&=~(1<<14);

USART波特率的设置是整个配置中比较关键的,stm32厂商已经给了我们一个公式:

【菜鸟入门】stm32 之 USART_第2张图片

USARTDIV计算出来,然后需要换算成USART_BRR寄存器需要的模式:我们呢可以先来研究下BRR寄存器:

【菜鸟入门】stm32 之 USART_第3张图片

他是把整数部分存放在4-15bit,小数部分存放在0~3bit

至于小数和整数部分的换算方法,STM也给提供了一个例子:

【菜鸟入门】stm32 之 USART_第4张图片

波特率计算完了,我们就需要对USART的控制寄存器进行设置,USART有三个控制器CR1,CR2,CR3

其中常用的只有CR1,CR2中只需配置一个参数。

关于这两个寄存器的详细信息请看25.6.4~26.6.7章,不过基本上看我的注释就可以看懂;

USART的中断配置,跟昨天那个按键中断配置一样,他的中断向量号是37

今天我重新把中断配置函数进行了整理,大家可以拿去用:

void init_interrupt(u8 group,u8 inter_id,u8 preempting,u8 subpriority)
{
	u32 aircr;
	u8  ip;
	
		/* Set Group :2 */
	aircr = SCB->AIRCR;		//Get AIRCR register
	aircr &= 0x0000f8ff;	//Clear Password & PriGroup
	aircr |= 0x05fa0000;	//Set Password
	aircr |= ((~group&0x7)<<8);		//Set PriGroup Group:2 0000 0010 => 1111 1101 [5 = 0101b]<<8
	SCB->AIRCR = aircr;		//Set AIRCR
		
		/* 
		 * Group 2  2:2
		 * 0~3 : 0~3
		 * Set Preempting = 0  Subpriority = 0
		 * 1001 0000b = 0x00;
		 */
	if(inter_id<32)
		NVIC->ISER[0] = 1<< inter_id;
	else
		NVIC->ISER[1] = 1<<(inter_id-32);	//EXIT15_10 vector:37
	switch(group)
	{
		case 0: ip = 0x0f&subpriority;break;
		case 1: ip = (0x08&preempting) | (0x07&subpriority);break;
		case 2: ip = (0x0C&preempting) | (0x03&subpriority);break;
		case 3: ip = (0x0e&preempting) | (0x01&subpriority);break;
		case 4: ip = 0x0f&preempting;break;
		default: ip = 0x00;break;
	}
	NVIC->IP[inter_id] = 0xf0&(ip<<4);
}



他的发送和中断接收函数也都很简单,其中发送和接受标志位,在对数据进行写,或者读的时候他会自动清除

int rs232_send_byte(u8 byte)
{
	USART1->DR = byte;
	while(0 == (USART1->SR&(1<<6)));
	return 1;
}

void USART1_IRQHandler(void)
{
	if(USART1->SR&(1<<5))
	{
		rs232_send_byte(USART1->DR);
	}
}

有了串口,我们以后调试程序就更方便,我们可以直接把寄存器值读出来,然后对初始化的寄存器值进行研究。




【菜鸟入门】stm32 之 USART

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
  任何USART通信,需要用到2个对外连接的引脚:RxD,TxD;  RxD是输入引脚,用于串行数据接收;
#include "stm32f0xx.h" #include "stm32_lib/inc/stm32f0xx_rcc.h" #include "stm32_lib/inc/stm32
啊啊啊,先叫两声,释放释放今天的压抑。。搞了一天终于把中断给搞定。 中断寄存器怎么说呢,两个字
2010年06月29日 星期二 20:56 终于开荤了~~~ DMA 先抄一小段DMA的说明。 对于没玩过DMA 的朋友,这里
经过今天一天的努力终于完成了我的stm32第一个程序;我也是今天才开始接触stm32。 由于苦于没有资料
如果此时USART正在发送数据,对USART_DR寄存器的写操作把数据存进TDR寄存器,并 在当前传输结束时把
下面跟大家说一下STM32单片机的端口重映射,因为是以自己为实例.这里是以USART1的重映射为例.. 因为
>_<!功能:PC端发送一个特定的字符:0x0d 0x0a,单片机则返回一句话,如图: >_<!知识
一、概念 USART 通用 同步异步收发器,全双工数据交换,利用分数波特率发生器提供宽范围的波特率选
在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器(下图中阴影部分的TDR),另一个是
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号