?導(dǎo)讀:《藍(lán)橋杯嵌入式組》專欄文章是博主2019年參加藍(lán)橋杯的嵌入式組比賽所做的學(xué)習(xí)筆記,在當(dāng)年的比賽中,由于忙于準(zhǔn)備考研及保研相關(guān)工作,博主僅僅參加了當(dāng)年的省賽,并獲得了省賽一等獎(jiǎng)的成績(jī)。成績(jī)雖談不上最好,但至少問心無愧。如今2021年回頭再看該系列文章,仍然感觸頗多。為了能更好地幫助到單片機(jī)初學(xué)者,今年特地抽出時(shí)間對(duì)當(dāng)年的文章邏輯和結(jié)構(gòu)進(jìn)行重構(gòu),以達(dá)到初學(xué)者快速上手的目的。需要指出的是,由于本人水平有限,如有錯(cuò)誤還請(qǐng)讀者指出,非常感謝。那么,接下來讓我們一起開始愉快的學(xué)習(xí)吧。
一、主要代碼
main.c
/*******************************************************************************
* 文件名:main.c
* 描 述:
* 作 者:CLAY
* 版本號(hào):v1.0.0
* 日 期: 2019年2月19日
* 備 注:修改后的LCD例程
* 采用定時(shí)器實(shí)現(xiàn)的簡(jiǎn)單1s計(jì)時(shí),實(shí)現(xiàn)LED1閃爍
*******************************************************************************
*/
#include "stm32f10x.h"
#include "lcd.h"
#include "e2prom.h"
#include "stdio.h"
#include "i2c.h"
#include "adc.h"
#include "rtc.h"
#include "usart2.h"
#include "pwm.h"
#include "pwm_oc.h"
#include "pwm_ic.h"
#include "timer.h"
#include "led.h"
u32 TimingDelay = 0;
u8 RxdCnt = 0;
u8 RxdOver = 0;
u8 RxdBuf[20];
void Delay_Ms(u32 nTime);
u8 RTC_Flag = 0;
//Main Body
int main(void)
{
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
SysTick_Config(SystemCoreClock/1000);
//PWM_Init(500, 60);//500Hz 60%方波//PA1
PWM_OC_Init(500, 60);//500Hz 60%方波 PA1
PWM_IC_Init();//PA7
TIM4_Init(10000, 7200);//定時(shí)1s
LED_Init();//LED配置
while(1)
{
}
}
//
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
led.c
#include "stm32f10x.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);//設(shè)能PC和PD口
//鎖存器IO配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//強(qiáng)推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//8個(gè)LED的IO配置
GPIO_InitStructure.GPIO_Pin = 0xFF00;//PC8~PC15對(duì)應(yīng)的LED位置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//強(qiáng)推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIOC->ODR |= 0xFF00;//初始狀態(tài)熄滅小燈
GPIOD->ODR |= (1<<2);//使能573
GPIOD->ODR &=~(1<<2);//失能573 注意是取非
}
led.h
#ifndef _LED_H
#define _LED_H
void LED_Init(void);
#endif
stm32f10x_it.c
...
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
GPIOC->ODR ^= (1<<8);//PC8不斷取反達(dá)到閃爍效果
GPIOD->ODR |= (1<<2);//使能573
GPIOD->ODR &= ~(1<<2);//失能573
}
}
...
二、注意事項(xiàng)
ODR寄存器
- ①、573在PD2 ; LED1在PC8
- ②、
GPIO_InitStructure.GPIO_Pin = 0xFF00;
//PC8~PC15對(duì)應(yīng)的LED位置 - ③、使能和失能573的操作 GPIOD->ODR |= (1<<2);//使能573 GPIOD->ODR &= ~(1<<2);//失能573,,別忘了取非!!!
- ④、改變LED狀態(tài)的操作技巧
GPIOC->ODR ^= (1<<8);//PC8不斷取反達(dá)到閃爍效果
- ⑤、先開鎖存器還是先給IO數(shù)據(jù)呢?
其實(shí)兩個(gè)照現(xiàn)象來看的話都可以,但是實(shí)則不然,573在里面起到了關(guān)鍵作用,我們就來分析下573。
給鎖存器的LE(N—LE,對(duì)應(yīng)PD2)管腳一個(gè)上升沿脈沖即可把對(duì)應(yīng)的電平鎖存到鎖存器的輸出端(Q1~Q8),從而控制LED。
換句話說,只要有一個(gè)從低到高的脈沖,就會(huì)直接把輸入端的數(shù)據(jù)給輸出端,所以更準(zhǔn)確來說應(yīng)該在開鎖存器前把數(shù)據(jù)準(zhǔn)備好,然后再拉高LE,鎖存完畢后再拉低LE為下次鎖存做準(zhǔn)備。
你可能會(huì)有疑問,連續(xù)拉高和拉低,之間的間隔夠不夠鎖存完數(shù)據(jù),這個(gè)口說無憑,需要參考手冊(cè)咯。
最小24ns,而STM32使用8M晶振的話,一個(gè)機(jī)器周期大概是1/8M=125ns,所以完全夠用,不必?fù)?dān)心的!
結(jié)語:以上就是本篇文章的全部?jī)?nèi)容啦,希望大家可以多多支持我的原創(chuàng)文章。如有錯(cuò)誤,請(qǐng)及時(shí)指正,非常感謝。