由于各种原因,参加了今年的蓝桥杯嵌入式,下面为大家分享我的备赛笔记(基础版)
觉得有用的sqgg和pljj可以给我点个赞,笔芯
本人文笔不好,只能用比较俗的话表达出来,多多包涵
在每次做真题的时候可以按照我的方法按顺序初始化每个外设
LED初始化-->KEY初始化-->定时器中断-->ADC采样、RTC、串口初始化、PWM输出与捕获-->E2PROM初始化
在写main.c 的时候可以根据模块分步写对应的函数(可以每个写一个函数,最后加到main函数的while循环里)
LCD显示-->ADC采样、RTC、串口初始化、PWM输出与捕获、定时器中断-->按键(长短按)、串口-->LED闪烁-->E2PROM数据存储与读取
1.要先熟悉每个外设的写代码方法
LED,LED的PC8到PC15会和LCD冲突,所以每次就涉及到锁存器的写法
每次写入LED都要先打开PD2的锁存器,再关闭PD2的锁存器,这样LED的PC8到PC15才可以写入
先定义GPIO结构体,使能APB1总线的GPIOC,GPIOD时钟,定义结构体各个参数
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC , ENABLE);
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_Init(GPIOD, &GPIO_InitStructure);
}
再写LED的控制函数
void led_control(u16 led,u8 state)
{
if(state==1)
{
GPIO_ResetBits(GPIOC,led<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
else
{
GPIO_SetBits(GPIOC,led<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
KEY的初始化:
注意初始化GPIO,PA0PA8PB1PB2KEY的初始化
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
这里使用的是三行按键代码
unsigned char Trg;
unsigned char Cont;
void key_read(void)
{
unsigned char keyread=(KEYPORT)^0xff;
//一定要加(),不然会检测不到按键
Trg=keyread&(keyread^Cont);
Cont=keyread;
}
定时器中断
一般使用的是TIM4中断,尽量不要选用TIM2,TIM3(做PWM输出和捕获时会用)
参考参赛时会给的数据包E:\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\TimeBase
void tim4_init(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* Enable the TIM4 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM4 enable counter */
TIM_Cmd(TIM4, ENABLE);
}
要把和TIM2相关的参数改成TIM4
频率为72000000/(71+1)/(999+1)=1KHz
RTC初始化
E:\1.蓝桥杯嵌入式\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\RTC
Calendar和LSI共同参照,把calendar的LSE换成LSI,copy NVIC中断, TIME_Adjust(),TIME_Display(),RTC_IRQHandler(),
改为全局变量uint32_t THH = 0, TMM = 0, TSS = 0;
或者使用定时器模拟RTC,在TIM4中断函数里定义shi,fen,miao变量
#include "rtc.h"__IO uint32_t TimeDisplay = 0;
//记得在main.c里也要定义一下这个变量extern __IO uint32_t TimeDisplay;
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the RTC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}void rtc_init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
/* Select the 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(40000);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* To output second signal on Tamper pin, the tamper functionality
must be disabled (by default this functionality is disabled) */
BKP_TamperPinCmd(DISABLE);
/* Enable the RTC Second Output on Tamper Pin */
//BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
NVIC_Configuration();
}void Time_Adjust(u8 Tmp_HH,u8 Tmp_MM,u8 Tmp_SS)
{
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Change the current time */
RTC_SetCounter(Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}/**
* @briefDisplays the current time.
* @paramTimeVar: RTC counter value.
* @retval None
*/
uint32_t THH = 0, TMM = 0, TSS = 0;
void Time_Display(uint32_t TimeVar)
{/* 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();
}/* Computehours */
THH = TimeVar / 3600;
/* Compute minutes */
TMM = (TimeVar % 3600) / 60;
/* Compute seconds */
TSS = (TimeVar % 3600) % 60;
printf("Time: %0.2d:%0.2d:%0.2d\r", THH, TMM, TSS);
}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;
RTC_WaitForLastTask();
}
}
RTC中断函数在rtc的it.c函数往下翻
E:\1.蓝桥杯嵌入式\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\RTC\Calendar
的main.c 里的void Time_Show(void)里有一个
if (TimeDisplay == 1)
{
/* Display current time */
Time_Display(RTC_GetCounter());
TimeDisplay = 0;
}
要加在主函数里,这样才能让时钟运行
I2C初始化
参考数据手册AT24C02中的Figure8,Figure11
写入间隔要有延时5ms
写入时高位/256,低位%256
Figure8为写
文章图片
Figure11为读
文章图片
void write(u8 add,u8 data)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
unsigned char read(u8 add)
{
u8 temp;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
temp=I2CReceiveByte();
I2CSendAck();
return temp;
}
PWM初始化 在代码库里找pwm输出的文件直接copy
1.这个只是比较简单的单个定时器输出多路相同频率不同占空比的方波
(TIM3一般只用到了PA6和PA7)
uint16_t CCR1_Val = 333;
uint16_t CCR2_Val = 249;
void pwm_output(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* -----------------------------------------------------------------------
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
The TIM3CLK frequency is set to SystemCoreClock (Hz), to get TIM3 counter
clock at 24 MHz the Prescaler is computed as following:
- Prescaler = (TIM3CLK / TIM3 counter clock) - 1
SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density
and Connectivity line devices and to 24 MHz for Low-Density Value line and
Medium-Density Value line devicesThe TIM3 is running at 36 KHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1)
= 24 MHz / 666 = 36 KHz
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
----------------------------------------------------------------------- */
/* Compute the prescaler value */
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 999;
//输出频率为1kHz
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
2.单个定时器输出多路不同频率、固定占空比的方波
在主函数里要修改变量,将TIM3_CCR1_Val和TIM3_CCR2_Val在pwm.h里声明为外部变量
TIM3_CCR1_Val = 2400; //TIM3_CH1频率 5KHz12000000Hz/2400=5000
TIM3_CCR2_Val = 4800; //TIM3_CH2频率 2.5KHz
__IO uint16_t CCR1_Val = 32768;
__IO uint16_t CCR2_Val = 16384;
__IO uint16_t CCR3_Val = 8192;
__IO uint16_t CCR4_Val = 4096;
uint16_t PrescalerValue = https://www.it610.com/article/0;
void tim3_octoggle()
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ---------------------------------------------------------------------------
TIM3 Configuration: Output Compare Toggle Mode:
TIM3CLK = SystemCoreClock / 2,
The objective is to get TIM3 counter clock at 12 MHz:
- Prescaler = (TIM3CLK / TIM3 counter clock) - 1
CC1 update rate = TIM3 counter clock / CCR1_Val = 366.2 Hz
CC2 update rate = TIM3 counter clock / CCR2_Val = 732.4 Hz
CC3 update rate = TIM3 counter clock / CCR3_Val = 1464.8 Hz
CC4 update rate = TIM3 counter clock / CCR4_Val = 2929.6 Hz
----------------------------------------------------------------------------*/
PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* TIM IT enable */
TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
}//TIM3的中断服务函数
void TIM3_IRQHandler(void)
{
/* TIM3_CH1 toggling with frequency = 183.1 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM3);
TIM_SetCompare1(TIM3, capture + CCR1_Val );
}/* TIM3_CH2 toggling with frequency = 366.2 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + CCR2_Val);
}
}
}
3.单个定时器输出多路不同频率、占空比的方波
__IO uint16_t TIM2_CCR2_Val = 8192;
__IO uint16_t TIM2_CCR3_Val = 4096;
void TIM2_PWM_OCToggle(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uint16_t PrescalerValue = https://www.it610.com/article/0;
/* System Clocks Configuration */
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
/* NVIC Configuration */
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* GPIO Configuration */
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);
/* ---------------------------------------------------------------------------
TIM2 Configuration: Output Compare Toggle Mode:
TIM2CLK = SystemCoreClock / 2,
The objective is to get TIM2 counter clock at 12 MHz:
- Prescaler = (TIM2CLK / TIM2 counter clock) - 1
CC1 update rate = TIM2 counter clock / CCR1_Val = 366.2 Hz
CC2 update rate = TIM2 counter clock / CCR2_Val = 732.4 Hz
CC3 update rate = TIM2 counter clock / CCR3_Val = 1464.8 Hz
CC4 update rate = TIM2 counter clock / CCR4_Val = 2929.6 Hz
----------------------------------------------------------------------------*/
/* Compute the prescaler value */
PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM2_CCR2_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM2_CCR3_Val;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_CC3 , ENABLE);
}uint16_t TIM2_capture = 0;
_Bool TIM2_CH2_flag=0, TIM2_CH3_flag=0;
float TIM2_CH2_duty=0.3, TIM2_CH3_duty=0.7;
void TIM2_IRQHandler(void)
{
/* TIM2_CH2 toggling with frequency = 732.4 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2 );
TIM2_capture = TIM_GetCapture2(TIM2);
if(TIM2_CH2_flag==1)
{
TIM_SetCompare2(TIM2, TIM2_capture + (u16)(TIM2_CCR2_Val*TIM2_CH2_duty));
TIM2_CH2_flag=0;
}
else
{
TIM_SetCompare2(TIM2, TIM2_capture + (u16)(TIM2_CCR2_Val*(1-TIM2_CH2_duty)));
TIM2_CH2_flag=1;
}
}/* TIM2_CH3 toggling with frequency = 1464.8 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
TIM2_capture = TIM_GetCapture3(TIM2);
if(TIM2_CH3_flag==1)
{
TIM_SetCompare3(TIM2, TIM2_capture + (u16)(TIM2_CCR3_Val*TIM2_CH3_duty));
TIM2_CH3_flag=0;
}
else
{
TIM_SetCompare3(TIM2, TIM2_capture + (u16)(TIM2_CCR3_Val*(1-TIM2_CH3_duty)));
TIM2_CH3_flag=1;
}
}
}
(本人比较菜,觉得这个就是最难的部分了)
ADC初始化
ADC结构体,GPIO结构体,时钟使能ADC1的通道8和GPIOB_0,
ADC_GetConversionValue(ADC1);
void adc_init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel8 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
USART初始化
E:\1.蓝桥杯嵌入式\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Utilities\STM32_EVAL\STM3210B_EVAL
找EVAL->103B->.c文件->(第328行)STM_EVAL_COMInit->再写个新函数usart2_init(在代码库的printf里)->USART_InitTypeDef USART_InitStructure->写sendstring函数和printf函数->写中断接收USART_ITConfig(一定要写)
咱们用的是COM2,但是并不用复用,所以删除GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
void STM_EVAL_COMInit( USART_InitTypeDef* USART_InitStruct)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART configuration */
USART_Init(USART2, USART_InitStruct);
/* Enable USART */
USART_Cmd(USART2, ENABLE);
}
void usart_init(void)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the USARTz Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
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;
STM_EVAL_COMInit(&USART_InitStructure);
//引用上面的代码,改下参数
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
void SendString(char *s)//自己写
{
while(*s)
{
USART_SendData(USART2,*s++);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)//USART_FLAG_TC 表示传输完毕;USART_FLAG_TXE表示发送缓冲区空
{}
}
}//或者在printf文件里找下面这个函数文件名在上面,具体函数在下面
int fputc(int ch, FILE *f)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART2, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
{}return ch;
}
再在interpret文件里找it.c文件,一般中断函数都在这个文件里
u8 rx_buf[20];
u8 rx_count=0;
_Bool rx_flag=0;
u16 rx_ideltime=0;
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
/* Read one byte from the receive data register */
rx_buf[rx_count++] = USART_ReceiveData(USART2);
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
if(rx_buf[5]=='\n')
{k=(rx_buf[3]-'0')/10.0f;
printf("ok\n");
write(0x01,(u8)(k*10));
}
}
}
这是第几届省赛的一个模板来着忘了,大概就这样,也可以写一个标志位usart_flag,在main.c里接受执行函数
【c语言|蓝桥杯嵌入式备赛】第一次写,可能不太严谨,也有许多错误和表达不清,如果有问题可以问本人,希望对你有所帮助,不要吝啬你的鼓励哦!一起加油!
推荐阅读
- 嵌入式|SmartTimer——一种基于STM32的轻量级时钟调度器
- 单片机|基于单片机的通用定时器调度器SmartTimer
- c语言|学习了循环碰到了编写计算n的阶乘的题目,由此引发了一系列问题,包括一些初学者常见的坑,以及如何简化代码
- c语言|你能用多少种方法字符串中的字符反向排列,要不看看我的
- c语言|n子棋,你能下赢电脑吗,来玩玩吧
- c语言|c语言初学者对scanf函数难分辨理解的两个点(欢迎补充)
- c语言药店管理系统|药店管理系统(c语言链表实现)
- linux技术成长|ARM中断向量表与响应流程
- 嵌入式|ARM 外部中断的过程