本次考试主要是双路PWM的输出控制;
①、库函数
②、初始化函数
init.c
#include "stm32f10x.h"
#include "lcd.h"
#include
#include "init.h"
#include "i2c.h"
void GPIO_Int(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
//LED
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//KEY
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
//RTC
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* Enable LSE */
RCC_LSICmd(ENABLE);
/* Wait till LSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(39999); /* RTC period = RTCCLK/RTC_PR = (40 KHz)/(3999+1) */
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_SetCounter(HH*3600+MM*60+SS);
NVIC_Configuration(); //rtc和usart中断
}
void LCD_Init(void)
{
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
SysTick_Config(SystemCoreClock/1000);
LCD_DisplayStringLine(Line0," ");
LCD_DisplayStringLine(Line1," PWM-PA1: 80% ");
LCD_DisplayStringLine(Line2," PWM-PA2: 10% ");
LCD_DisplayStringLine(Line3," Time: 23:59:50 ");
LCD_DisplayStringLine(Line4," Channel: None ");
LCD_DisplayStringLine(Line5," Command: ");
LCD_DisplayStringLine(Line6," None ");
LCD_DisplayStringLine(Line7," ");
LCD_DisplayStringLine(Line8," ");
LCD_DisplayStringLine(Line9," ");
}
void USART2_Configuration(void) //因为之后需要,特地将usart初始化单独出来 (PWM)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure USARTz Rx as input floating */
GPIO_InitStructure.GPIO_Pin = USARTz_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USART2 */
USART_Init(USART2, &USART_InitStructure);
/* Enable USARTz Receive interrupts */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
/* Enable the USARTz */
USART_Cmd(USART2, ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USARTz Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_Configuration(u16 CCR2_Val,u16 CCR3_Val)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
unsigned char IIC_Read(unsigned char add)
{
unsigned char temp;
I2CStart();
I2CSendByte(0xa0);
I2CSendAck();
I2CSendByte(add);
I2CSendAck();
I2CStart();
I2CSendByte(0xa1);
I2CSendAck();
temp=I2CReceiveByte();
I2CSendAck();
I2CStop();
return (temp);
}
void IIC_Write(unsigned char add,unsigned char dat)
{
I2CStart();
I2CSendByte(0xa0);
I2CSendAck();
I2CSendByte(add);
I2CSendAck();
I2CSendByte(dat);
I2CSendAck();
I2CStop();
}
init.h
#ifndef __INIT_H
#define __INIT_H
#include "stm32f10x.h"
#define RB1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define RB2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
#define RB3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define RB4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)
#define USARTz_RxPin GPIO_Pin_3
#define HH 23
#define MM 59
#define SS 50
void GPIO_Int(void);
void LCD_Init(void);
void TIM2_Configuration(u16 CCR2_Val,u16 CCR3_Val);
void NVIC_Configuration(void);
void USART2_Configuration(void);
void IIC_Write(unsigned char add,unsigned char dat);
unsigned char IIC_Read(unsigned char add);
#endif
③、主函数
#include "stm32f10x.h"
#include "lcd.h"
#include
#include "init.h"
#include "i2c.h"
u32 TimingDelay = 0;
u8 RX_Buff[20];
u8 Receive=0;
u8 string[20];
u8 PA1=0,PA2=0;
u16 CCR2_Val;
u16 CCR3_Val;
u8 BHH=0,BMM=0,BSS=0;
__IO uint32_t TimeDisplay=0;
void Delay_Ms(u32 nTime);
void LCD_Init(void);
void GPIO_Int(void);
void KEY_Scan(void);
void Time_Display(uint32_t TimeVar);
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
LCD_Init();
GPIO_Int();
i2c_init();
//TIM2_Configuration(500,800);
USART2_Configuration();
if(IIC_Read(0x20)!=20)
{
Delay_Ms(5);
IIC_Write(0x00,70);
Delay_Ms(5);
IIC_Write(0x01,5);
Delay_Ms(5);
IIC_Write(0x20,20);
}
Delay_Ms(5);
CCR2_Val=IIC_Read(0x00);
Delay_Ms(5);
CCR3_Val=IIC_Read(0x01);
sprintf((char*)string," PWM-PA1: %.2d%%",CCR2_Val);
LCD_DisplayStringLine(Line1,string);
sprintf((char*)string," PWM-PA2: %.2d%%",CCR3_Val);
LCD_DisplayStringLine(Line2,string);
while (1)
{
KEY_Scan();
if(Receive==1)
{
Receive=0;
LCD_DisplayStringLine(Line6,RX_Buff);
BHH=(RX_Buff[3]-48)*10+RX_Buff[4]-48;
BMM=(RX_Buff[6]-48)*10+RX_Buff[7]-48;
BSS=(RX_Buff[9]-48)*10+RX_Buff[10]-48; //注意ascii码,故需转化
// sprintf((char*)string,"BHH:%d BMM:%d BSS:%d",BHH,BMM,BSS);
// LCD_DisplayStringLine(Line9,string);
}
if (TimeDisplay == 1)
{
/* Display current time */
Time_Display(RTC_GetCounter());
TimeDisplay = 0;
}
}
}
void KEY_Scan(void)
{
if(RB1==0)
{
Delay_Ms(10);
if(RB1==0)
{
if(PA1==0)
{
PA1=1;
TIM2_Configuration(CCR2_Val*10,0);
LCD_DisplayStringLine(Line4," Channel: PA1 ");
GPIO_SetBits(GPIOC,GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_ResetBits(GPIOC,GPIO_Pin_8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
else if(PA1==1)
{
PA1=0;
TIM2_Configuration(0,0);
LCD_DisplayStringLine(Line4," Channel: None ");
GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
while(!RB1);
}
else if(RB2==0)
{
Delay_Ms(10);
if(RB2==0)
{
CCR2_Val+=10;
if(CCR2_Val>=100)
{
CCR2_Val=10;
}
Delay_Ms(5);
IIC_Write(0x00,CCR2_Val);
sprintf((char*)string," PWM-PA1: %.2d%",CCR2_Val);
LCD_DisplayStringLine(Line1,string);
if(PA1==1)
{
TIM2_Configuration(CCR2_Val*10,0);
}
}
while(!RB2);
}
else if(R3==0)
{
Delay_Ms(10);
if(RB3==0)
{
if(PA2==0)
{
PA2=1;
LCD_DisplayStringLine(Line4," Channel: PA2 ");
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
/* Disable the USARTz */
USART_Cmd(USART2, DISABLE); //因为usart与pwm共用引脚PA2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
TIM2_Configuration(0,CCR3_Val*10);
GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_ResetBits(GPIOC,GPIO_Pin_9);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
else if(PA2==1)
{
PA2=0;
TIM2_Configuration(0,0);
LCD_DisplayStringLine(Line4," Channel: None ");
USART2_Configuration();
GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
while(!RB3);
}
else if(RB4==0)
{
Delay_Ms(10);
if(RB4==0)
{
CCR3_Val+=10;
if(CCR3_Val>=100)
{
CCR3_Val=10;
}
Delay_Ms(5);
IIC_Write(0x01,CCR3_Val);
sprintf((char*)string," PWM-PA2: %.2d%",CCR3_Val);
LCD_DisplayStringLine(Line2,string);
if(PA2==1)
{
TIM2_Configuration(CCR3_Val*10,0);
}
}
while(!RB4);
}
}
void Time_Display(uint32_t TimeVar)
{
uint32_t THH = 0, TMM = 0, TSS = 0;
/* Reset RTC Counter when Time is 23:59:59 */
if (RTC_GetCounter() == 0x0001517F)
{
RTC_SetCounter(0x0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/* Compute hours */
THH = TimeVar / 3600;
/* Compute minutes */
TMM = (TimeVar % 3600) / 60;
/* Compute seconds */
TSS = (TimeVar % 3600) % 60;
if(THH==BHH)
{
if(TMM==BMM)
{
if(TSS==BSS)
{
if(RX_Buff[14]=='1')
{
TIM2_Configuration(CCR2_Val*10,0);
LCD_DisplayStringLine(Line4," Channel: PA1 ");
GPIO_SetBits(GPIOC,GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_ResetBits(GPIOC,GPIO_Pin_8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
else if(RX_Buff[14]=='2')
{
LCD_DisplayStringLine(Line4," Channel: PA2 ");
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
/* Disable the USARTz */
USART_Cmd(USART2, DISABLE); //因为usart与pwm共用引脚PA2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
TIM2_Configuration(0,CCR3_Val*10);
GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_ResetBits(GPIOC,GPIO_Pin_9);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
else if(TSS==BSS+RX_Buff[16]-48)
{
TIM2_Configuration(0,0);
LCD_DisplayStringLine(Line4," Channel: None ");
if(RX_Buff[14]=='2')
{
USART2_Configuration();
}
GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
}
sprintf((char*)string," Time: %.2d:%.2d:%.2d", THH, TMM, TSS);
LCD_DisplayStringLine(Line3,string);
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
④、中断服务函数
u8 Counter=3;
void USART2_IRQHandler(void)
{
u8 temp;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
/* Read one byte from the receive data register */
temp = USART_ReceiveData(USART2);
if(temp == 'S') //注意是字符所以单引号,下同
{
RX_Buff[Counter]=temp;
Receive=1;
Counter=3;
}
else
{
RX_Buff[0]=' ';
RX_Buff[1]=' ';
RX_Buff[2]=' '; //为了美观,显示三个空格
RX_Buff[Counter]=temp;
Counter++;
}
}
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
/* Enable time update */
TimeDisplay = 1;
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
⑤、代码分析
本次考试的难点在于,由于usart接受引脚为PA2,而PWM2的输出引脚也是PA2这就导致了,当我们需要PWM波时需要关闭USART功能,即失能usart的接受中断,开启命令和时钟;其次usart接收到的是字符串,即ascii码故在处理时尤其在转换为数字时需要减去48,同时为了美观接收到的前三个字符设置为空格,使其在lcd上显示不至于靠边;另外为了关闭开启usart的方便特地将其初始化单独出来。
具体程序和试题