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亮*/
}
}