UART发送实现printf输出,UART利用空闲中断实现接收,用PWM驱动LED0,判断UART接收的字符,相应调节LED亮度,‘1’最暗,‘9’最亮

1、UART发送实现printf输出;
2、UART利用空闲中断实现接收;
3、用PWM驱动LED0;
4、判断UART接收的字符,相应调节LED亮度,‘1’最暗,‘9’最亮;

遇到的问题:
1、串口部分的函数
2、PWM相关的计算
3、红外遥控器控制,NEC协议,输入捕获这方面认识不足,需要再看一看

实现代码

PWM.C

#include "stm32f10x.h"                  // Device header

/*在定时中断的基础上,配置时基单元*/
void PWM_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
   
    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);     //先打开AFIO时钟
    //GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);    //PA0换到PA15
    //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //再用 AFIO将JTAG复用解除掉
    
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //推挽复用输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIO_Pin_15;      //选定一二号口
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    TIM_DeInit(TIM1);
    
    TIM_InternalClockConfig(TIM1);
    
    /*时基单元配置*/
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;       //ARR
    TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;     //PSC
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;    //高级定时器
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
    
    /*开启更新中断到NVIC的通路*/
//    TIM_ClearFlag(TIM1, TIM_FLAG_Update);
//    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
//    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//    NVIC_InitTypeDef NVIC_InitStructure;
//    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  //???TIM1_UP_IRQn
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//    NVIC_Init(&NVIC_InitStructure);
 
    /*输出比较单元配置*/
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);         //赋初值,再改

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;   //设置输出比较模式
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //设置输出比较极性
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //设置输出使能
    TIM_OCInitStructure.TIM_Pulse = 0;              //设置CCR
    
    TIM_OC1Init(TIM1, &TIM_OCInitStructure); 
    
    TIM_Cmd(TIM1, ENABLE);
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}



//不断改变占空比
void PWM_SetComparel(uint16_t Compare)
{
    TIM_SetCompare1(TIM1, Compare);
}

PWM.h

#ifndef __PWM_H__
#define __PWM_H__

void PWM_Init(void);
void PWM_SetComparel(uint16_t Compare);

#endif

Serial.c

#include "stm32f10x.h"                  // Device header
#include "stdio.h"
#include "stdarg.h"

uint8_t Serial_RxData;
uint8_t Serial_RxFlag;


void Serial_Init(void)
{
    //Turn on the clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    
    //USART1 transmit
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;   //PA9——U1TXD,PA10——U1RXD
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    //USART1 receive
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    //Configure USART1
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStructure);       //Neg
    
    //Open interrupt
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //Neg
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Neg
    
    //Configure interrupt
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;    //?
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
    
    //Serial enable
    USART_Cmd(USART1, ENABLE);    
}

void Serial_SendByte(uint8_t Byte)  //Wrong parameter
{
    USART_SendData(USART1, Byte);          //Fgt
    
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);    //The wrong register and flag were selected
}

void Serial_SendString(char *String)
{
    uint8_t i;
    for (i = 0; String[i] != '\0'; i ++)    //Pay more attention to
    {
        Serial_SendByte(String[i]);
    }
}

void Serial_Printf(char *format, ...)
{
    char String[100];
    va_list arg;
    
    va_start(arg, format);
    vsprintf(String, format, arg);
    va_end(arg);
    
    Serial_SendString(String);
}

uint8_t Serial_GetRxFlag(void)
{
    if(Serial_RxFlag == 1)
    {
        Serial_RxFlag = 0;
        return 1;
    }
    return 0;
}

uint8_t Serial_GetRxData(void)
{
    return Serial_RxData;       //Data received
}

int fputc(int ch, FILE *F)      //Neg:An int has a return value
{
    Serial_SendByte(ch);
    return ch;
}

void USART1_IRQHandler(void)
{
    while (USART_GetFlagStatus(USART1, USART_IT_RXNE) == SET) //Wrong function,not USART_FLAG_RXNE
    {
        Serial_RxData = USART_ReceiveData(USART1);
        Serial_RxFlag = 1;              //Neg
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);      //Neg
    }  
}

Serial.h

#ifndef __SERIAL_H__
#define __SERIAL_H__

#include <stdio.h>

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendString(char *String);
void Serial_Printf(char *format, ...);
uint8_t Serial_GetRxData(void);
uint8_t Serial_GetRxFlag(void);
int fputc(int ch, FILE *F);
void USART1_IRQHandler(void);


#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "PWM.h"
#include "LED.h"
#include "Key.h"
#include "stdint.h"
#include "Serial.h"


uint8_t i;
uint8_t KeyNum;
uint8_t RxData;

int main(void)
{
    //Key_Init();
    //LED_Init();
    
    Serial_Init();
    PWM_Init();

    while(1)
    {   
        if (Serial_GetRxFlag() == 1)
        {
            RxData = Serial_GetRxData();
            Serial_SendByte(RxData);
            
            PWM_SetComparel(100 - RxData * 10);
            Delay_ms(10);
        }
        
        
        /*
        for (i = 0; i <= 100; i++)
        {
            PWM_SetComparel(i); //设置CCR寄存器的值,通过CCR修改占空比
            Delay_ms(10);
        }
        
        for(i = 0; i <= 100; i++)   //占空比100→0
        {
            PWM_SetComparel(100 - i);
            Delay_ms(10);
        }
        */
        
        
        /*红绿交替闪烁            
        LED0_OFF();
        Delay_ms(100);
        LED1_ON();
        Delay_ms(100);
        LED0_ON();
        Delay_ms(100);
        LED1_OFF();
        Delay_ms(100);
        红绿交替闪烁  */

        
        /*按键Key0/1控制LED0/1亮
        KeyNum = Key_GetNum();
        if (KeyNum == 0)
        {
            LED0_Turn();
        }
        if (KeyNum == 1)
        {
            LED1_Turn();
        }
        按键Key0/1控制LED0/1亮*/
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FM33lc026n是一款基于ARM Cortex-M0+内核的微控制器,支持多种外设,包括UART和DMA。要实现不定长度的数据接收,可以采用空闲中断加DMA加UART的方式。 首先,在UART接收数据时,需要开启空闲中断。当接收到一帧数据后,UART会产生空闲中断,表示数据接收完成。在空闲中断中,可以获取接收到的数据长度,并将接收到的数据存储到缓冲区中。 接下来,使用DMA将数据从UART接收缓冲区中传输到指定的内存地址。在配置DMA时,需要设置传输长度为接收到的数据长度,并开启循环模式,以便在下一次接收数据时继续传输。 最后,可以在DMA传输完成中断中进行一些操作,比如通知主程序数据已经接收完成。 以下是一个简单的代码示例: ```c #include "fm33lc0xx_fl_dma.h" #include "fm33lc0xx_fl_uart.h" #define BUFFER_SIZE 1024 uint8_t uart_rx_buffer[BUFFER_SIZE]; volatile uint32_t uart_rx_length = 0; void UART_IDLE_IRQHandler(void) { if (FL_UART_IsActiveFlag_IDLE(FL_UART1)) { FL_UART_ClearFlag_IDLE(FL_UART1); uart_rx_length = BUFFER_SIZE - FL_DMA_GetCurrDataCounter(DMA1, FL_DMA_CH3); } } void DMA1_Channel3_IRQHandler(void) { if (FL_DMA_IsActiveFlag_TC(DMA1, FL_DMA_CH3)) { FL_DMA_ClearFlag_TC(DMA1, FL_DMA_CH3); // do something after data transfer completed } } int main(void) { // initialize UART and DMA FL_UART_InitTypeDef uart_init_struct = {0}; uart_init_struct.UART_BaudRate = 115200; FL_UART_Init(UART1, &uart_init_struct); FL_DMA_InitTypeDef dma_init_struct = {0}; dma_init_struct.Init.Priority = FL_DMA_PRIORITY_HIGH; dma_init_struct.Init.PeriphDataAlignment = FL_DMA_DATA_WIDTH_BYTE; dma_init_struct.Init.MemDataAlignment = FL_DMA_DATA_WIDTH_BYTE; dma_init_struct.Init.PeriphInc = FL_DMA_PERIPH_INC_DISABLE; dma_init_struct.Init.MemInc = FL_DMA_MEM_INC_ENABLE; dma_init_struct.Init.Mode = FL_DMA_MODE_NORMAL; dma_init_struct.Init.Dir = FL_DMA_DIR_PERIPH_TO_MEM; dma_init_struct.Init.DataSize = FL_DMA_DATA_WIDTH_BYTE; dma_init_struct.Init.Ndtr = BUFFER_SIZE; dma_init_struct.Init.PBurst = FL_DMA_BURST_SINGLE; dma_init_struct.Init.MBurst = FL_DMA_BURST_SINGLE; FL_DMA_Init(DMA1, FL_DMA_CH3, &dma_init_struct); // configure DMA transfer FL_DMA_SetPeriphAddress(DMA1, FL_DMA_CH3, (uint32_t)&(UART1->DR)); FL_DMA_SetMemoryAddress(DMA1, FL_DMA_CH3, (uint32_t)uart_rx_buffer); FL_DMA_EnableIT_TC(DMA1, FL_DMA_CH3); // enable UART idle interrupt FL_UART_EnableIT_IDLE(UART1); FL_IRQ_Enable(UART1_IDLE_IRQn); // enable DMA channel and interrupt FL_DMA_EnableChannel(DMA1, FL_DMA_CH3); FL_IRQ_Enable(DMA1_Channel3_IRQn); while (1) { // do something else } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值