本讲主要实现usart TX的实现,主要分几部分的应用
1.USART 1 Tx polling的实现(附带printf的实现)
2.USART1 Tx DMA的实现
3.USART1 TX DMA中断的实现
话不多说,开始
一.硬件原理图
USART1在APB2总线上
二.寄存器图
寄存器可以参考 参考手册,在这里不做详细讨论
三.具体实现
1. USART 1 Tx polling的实现(附带printf的实现)
1) 编程步骤:
->使能PA9的时钟
->使能USART1的时钟
->配置PA9为推挽复用输出
->配置USART1的波特率为115200(因为USART1在APB2上,计算方法为APB2 clock/波特率)
->使能USART1和TX和USART1
->Polling方式往USART1的DR寄存器填数据
->printf需要重定向fputc
2) 程序调试
->程序调用
USART1_Init();
USART1_TX_Polling(100);
->使能PA9,USART1的时钟
/* 1.ENABLE USART1 GPIOA CLOCK */
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
/* 2. ENABLE USART1 IN APB2 BUS CLOCK */
RCC->APB2ENR |=RCC_APB2ENR_USART1EN;
->配置PA9为推挽复用输出
/* 3.CONFIG GPIOA PA9 AF MODE */
GPIOA->CRH &= ~(GPIO_CRH_MODE9 |GPIO_CRH_CNF9);
GPIOA->CRH |=GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1;
此处需要注意一个特别重要的细节:因为CRH默认的value是:
所以如果没有清除到bit4-bit7,直接进行或运算就会造成错误,成为开漏模式,CRL寄存器同样道理,正常运行如图:
->配置波特率为115200
USART1->BRR |= 0x271;
运行效果图
->使能USART1和USART1 TX
USART1->CR1 |= USART_CR1_UE | USART_CR1_TE |USART_CR1_RE;
-> Polling方式往USART1的DR寄存器填数据
voidUSART1_TX_Polling(int loop_cnt)
{
int index = 0;
for(;index < loop_cnt;index++)
{
while ((USART1->SR &USART_SR_TXE) == 0);
USART1->DR= 'a';
}
while(1);
}
运行图
->printf fputc重定向
int fputc(int ch, FILE *fp)
{
if (fp == stdout)
{
if (ch == '\n')
{
while((USART1->SR & USART_SR_TXE) == 0);
USART1->DR ='\r';
}
while ((USART1->SR &USART_SR_TXE) == 0);
USART1->DR = ch;
}
return ch;
}
2. USART1 Tx DMA的实现
1) 编程步骤
->使能PA9的时钟
->使能USART1的时钟
->配置PA9为推挽复用输出
->配置USART1的波特率为115200(因为USART1在APB2上,计算方法为APB2 clock/波特率)
->使能USART1和TX和USART1
->设置DMA,请参照DMA文章:
http://blog.csdn.net/xiaoxiaopengbo/article/details/77434744
程序源码
unsigned char buffer[52] = "DMA DATA TEST";
void USART1_TX_DMA()
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAT;
/* 6. CONFIG DMA */
DMA1_Channel4->CMAR = (uint32_t)buffer;
DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;
DMA1_Channel4->CNDTR = strlen(buffer);
DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;
while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);
DMA1->IFCR = DMA_IFCR_CTCIF4;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
while(1);
}
程序调试图:
3. USART1 TX DMA中断的实现
1) 编程步骤
->设置USART1
->设置DMA以及NVIC中断
->编写DMA中断函数
2) 程序源码
void USART1_TX_DMA_IRPT()
{
NVIC_SetPriorityGrouping(4);
NVIC_SetPriority(DMA1_Channel4_IRQn, 1);
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAT;
/* 6. CONFIG DMA */
DMA1_Channel4->CMAR = (uint32_t)buffer;
DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;
DMA1_Channel4->CNDTR = strlen(buffer);
DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_TCIE | DMA_CCR5_HTIE | DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);
DMA1->IFCR = DMA_IFCR_CTCIF4;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
while(1);
}
3) 程序调试
四. 整个程序源码
#include
#include
unsigned char buffer[52] = "DMA DATA TEST";
void USART1_Init()
{
/* 1. ENABLE USART1 GPIOA CLOCK */
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
/* 2. ENABLE USART1 IN APB2 BUS CLOCK */
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
/* 3. CONFIG GPIOA PA9 AF MODE */
GPIOA->CRH &= ~(GPIO_CRH_MODE9 |GPIO_CRH_CNF9);
GPIOA->CRH |= GPIO_CRH_MODE9 |GPIO_CRH_CNF9_1;
GPIOA->CRH &= ~(GPIO_CRH_MODE10 |GPIO_CRH_CNF10);
GPIOA->CRH |= GPIO_CRH_CNF10_1;
/* 4. CONFIG USART1 BAUD RATE 115200 */
USART1->BRR |= 0x271;
/* 5. ENBALE TRANSPORT AND ENABLE USART1 */
USART1->CR1 |= USART_CR1_UE |USART_CR1_TE | USART_CR1_RE;
}
void USART1_TX_Polling(int loop_cnt)
{
int index = 0;
for(;index < loop_cnt;index++)
{
while ((USART1->SR &USART_SR_TXE) == 0);
USART1->DR = 'a';
}
while(1);
}
void USART1_TX_DMA()
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAT;
/* 6. CONFIG DMA */
DMA1_Channel4->CMAR = (uint32_t)buffer;
DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;
DMA1_Channel4->CNDTR = strlen(buffer);
DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;
while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);
DMA1->IFCR = DMA_IFCR_CTCIF4;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
while(1);
}
void DMA1_Channel4_IRQHandler(void)
{
if (DMA1->ISR & DMA_ISR_HTIF4)
{
DMA1->IFCR = DMA_IFCR_CHTIF4;
//printf("HTIF: %d\n",DMA1_Channel4->CNDTR);
}
if (DMA1->ISR & DMA_ISR_TCIF4)
{
DMA1->IFCR = DMA_IFCR_CTCIF4;
//printf("TCIF: %d\n",DMA1_Channel4->CNDTR);
}
}
void USART1_TX_DMA_IRPT()
{
NVIC_SetPriorityGrouping(4);
NVIC_SetPriority(DMA1_Channel4_IRQn, 1);
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAT;
/* 6. CONFIG DMA */
DMA1_Channel4->CMAR = (uint32_t)buffer;
DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;
DMA1_Channel4->CNDTR = strlen(buffer);
DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_TCIE | DMA_CCR5_HTIE | DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);
DMA1->IFCR = DMA_IFCR_CTCIF4;
DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
while(1);
}
int fputc(int ch, FILE *fp)
{
if (fp == stdout)
{
if (ch == '\n')
{
while ((USART1->SR& USART_SR_TXE) == 0);
USART1->DR = '\r';
}
while ((USART1->SR &USART_SR_TXE) == 0);
USART1->DR = ch;
}
return ch;
}
int main()
{
USART1_Init();
// USART1_TX_Polling(100);
// USART1_TX_DMA();
//USART1_TX_DMA_IRPT();
while(1);
}
上一篇:【stm32f103】stm32 外部中断(寄存器版)
下一篇:【stm32f103】SysTick实现延时(寄存器版)
推荐阅读最新更新时间:2024-03-16 16:23