历史上的今天
返回首页

历史上的今天

今天是:2025年01月29日(星期三)

2019年01月29日 | STM32基础设计(7)---时钟中断(控制LED灯)

2019-01-29 来源:eefocus

本文将介绍STM32的基础时钟,通过时钟中断来控制LED灯的亮灭。


本文的大致思路如下:


1,LED的GPIO口初始化


2,中断初始化


3,时钟初始化


4,编写中断函数


5,编写主函数


首先讲下笔者在做这个设计时得到的教训:


        笔者最初是用TIM6基础时钟来实现设计功能,在编写完代码后发现,灯不亮,于是笔者就开始整问题了。先看看代码有没有编写错误,检查一遍后,中断通道使用正确,TIM6配置正确,LED灯的串口也没有问题,中断函数也正常编写了。然后笔者纠结了,他妈代码全对了怎么就运行失败?(原谅笔者爆粗口,因为当时心情的确很不好,可以想象一下,辛辛苦苦桥的代码,没什么毛病,结果到了板子上还运行不了)之后笔者认认真真核对代码,还是没解决问题,之后没办法了,去论坛上请教大佬去了,(还是大佬厉害)我把问题说了后,大佬看了后说,可能是你的启动文件里没有TIM6中断(笔者顿悟了),他妈我怎么没想到这个。。。之后去检查发现果然没有这个中断函数入口(STM32中必须按照要求写中断函数名才能进入中断),之后笔者发现我的工程中定义的是STM32F10X_MD这个头文件,这个头文件里没有TIM6这个中断名(当初笔者也发现了这个问题,自己看定义了个#define 54(因为我查了其他头文件是54)),又检查了启动文件,发现没有写中断函数入口,笔者就把TIM6换成TIM3(通用定时器)了,之后就正常了。希望可以帮助到和我犯同样错误的人。


下面进入主题,详细解释代码:


1,LED的GPIO口初始化

void led_init()

{

GPIO_InitTypeDef led_gpio;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);因为GPIOC13口的13引脚被重映射了,所以需要先关闭重映射

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);

led_gpio.GPIO_Pin = GPIO_Pin_13;

led_gpio.GPIO_Mode = GPIO_Mode_Out_PP;

led_gpio.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&led_gpio);

}

2,中断初始化

void nvic_init()

{

NVIC_InitTypeDef nvic;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);定义分组

nvic.NVIC_IRQChannel  =TIM3_IRQn;中断通道名

nvic.NVIC_IRQChannelPreemptionPriority = 1;

nvic.NVIC_IRQChannelSubPriority = 0;

nvic.NVIC_IRQChannelCmd= ENABLE;中断时能

NVIC_Init(&nvic);初始化寄存器

}

3,时钟初始化

void tim_init()

{

TIM_TimeBaseInitTypeDef tim;定义时钟结构体

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);时能TIM3

tim.TIM_Period = 1000-1;计数周期

tim.TIM_Prescaler = 72 - 1;预分频数

tim.TIM_ClockDivision = TIM_CKD_DIV1;时钟分频,设置定时器时钟CK_INT频率与数字滤波器采样时钟频率分频比,基本定时器没有此功能

tim.TIM_CounterMode = TIM_CounterMode_Up;定时器基础方式,可以是向上计数、向下计数、中心对其模式。基本定时器只能是向上计数。

tim.TIM_RepetitionCounter = 0;重复计数器,属于高级控制寄存器专用寄存器位,这里不用设置。

TIM_TimeBaseInit(TIM3,&tim);初始化

TIM_ClearFlag(TIM3,TIM_FLAG_Update);清除中断标志

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);开启中断

TIM_Cmd(TIM3,ENABLE);TIM3使能

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,DISABLE);关闭TIM3时钟,等需要时在打开

}

4,编写中断服务函数

void TIM3_IRQHandler()

{

if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET){判断是否可以中断

//PrintString("\r\ntime inter");这个是笔者在调试程序时用的串口

time++;

if(time >=1000)实现1秒一计数

{

//PrintString("\r\nin time inter");

time = 0;以下是实现灯的亮灭

if(GPIOC->ODR & GPIO_Pin_13)

{

GPIOC->BRR = GPIO_Pin_13;

}else

{

GPIOC->BSRR = GPIO_Pin_13;

}

}

}

TIM_ClearITPendingBit(TIM3,TIM_FLAG_Update);清除中断标志位避免重复进入中断

}


5,主函数

int main()

{

led_init();LED初始化

tim_init();时钟初始化

nvic_init();中断初始化

//nvic_usart_init();

//usart_init();

GPIOC->BSRR = GPIO_Pin_13;预先打开灯

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);使能TIM3

delay(1000);延时1秒

while(1){死循环

//PrintString("\r\nÑ­»·");

}

}


下面粘贴详细代码:


注:注释掉的部分是笔者用串口在调试程序,可忽略(笔者经验有限,如有不妥之处请指教)


#include

static unsigned int time;

uint8_t TxCount=0;

uint8_t Count=0;

static uint8_t TxBuff[256];

void delay(uint16_t n)

{

int i,j;

for(i=0;i

for(j=0;j<8500;j++);

}

void tim_init()

{

TIM_TimeBaseInitTypeDef tim;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

tim.TIM_Period = 1000-1;

tim.TIM_Prescaler = 71;

tim.TIM_ClockDivision = TIM_CKD_DIV1;

tim.TIM_CounterMode = TIM_CounterMode_Up;

tim.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM3,&tim);

TIM_ClearFlag(TIM3,TIM_FLAG_Update);

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);

TIM_Cmd(TIM3,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,DISABLE);

}

void PrintU8(uint8_t data)

{

TxBuff[TxCount++]=data;

if(!(USART1->CR1 & USART_CR1_TXEIE))

{

USART_ITConfig(USART1,USART_IT_TXE,ENABLE);

}

}

 

void PrintString(uint8_t *s)

{

uint8_t *p;

p=s;

while(*p != '\0')

{

PrintU8(*p);

p++;

}

}

void usart_init()

{

GPIO_InitTypeDef Uart_A;  

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 

Uart_A.GPIO_Pin = GPIO_Pin_9;  

    Uart_A.GPIO_Speed = GPIO_Speed_50MHz;  

    Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_Init(GPIOA,&Uart_A);  

      

    Uart_A.GPIO_Pin = GPIO_Pin_10;  

    Uart_A.GPIO_Speed = GPIO_Speed_50MHz;  

    Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 110  

    GPIO_Init(GPIOA,&Uart_A);  

USART_InitTypeDef Uart;  

      

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  

    Uart.USART_BaudRate = 115200;  

    Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

    Uart.USART_Mode = USART_Mode_Tx;  

    Uart.USART_Parity = USART_Parity_No;  

    Uart.USART_StopBits = USART_StopBits_1;  

    Uart.USART_WordLength = USART_WordLength_8b;  

    USART_Init(USART1,&Uart);  

      

    USART_Cmd(USART1,ENABLE);  

    USART_ClearFlag(USART1,USART_FLAG_TC);

}

void nvic_usart_init()

{

NVIC_InitTypeDef nvic;  

      

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  

      

    nvic.NVIC_IRQChannelPreemptionPriority = 0;  

    nvic.NVIC_IRQChannelSubPriority = 0;  

    nvic.NVIC_IRQChannel = USART1_IRQn;  

    nvic.NVIC_IRQChannelCmd = ENABLE;  

    NVIC_Init(&nvic);  

}

void nvic_init()

{

NVIC_InitTypeDef nvic;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

nvic.NVIC_IRQChannel  =TIM3_IRQn;

nvic.NVIC_IRQChannelPreemptionPriority = 1;

nvic.NVIC_IRQChannelSubPriority = 0;

nvic.NVIC_IRQChannelCmd= ENABLE;

NVIC_Init(&nvic);

}

void led_init()

{

GPIO_InitTypeDef led_gpio;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);

led_gpio.GPIO_Pin = GPIO_Pin_13;

led_gpio.GPIO_Mode = GPIO_Mode_Out_PP;

led_gpio.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&led_gpio);

}

int main()

{

led_init();

tim_init();

nvic_init();

//nvic_usart_init();

//usart_init();

GPIOC->BSRR = GPIO_Pin_13;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

delay(1000);

while(1){

//PrintString("\r\nÑ­»·");

}

}

void TIM3_IRQHandler()

{

if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET){

//PrintString("\r\ntime inter");

time++;

if(time >=1000)

{

//PrintString("\r\nin time inter");

time = 0;

if(GPIOC->ODR & GPIO_Pin_13)

{

GPIOC->BRR = GPIO_Pin_13;

}else

{

GPIOC->BSRR = GPIO_Pin_13;

}

}

}

TIM_ClearITPendingBit(TIM3,TIM_FLAG_Update);

}

void USART1_IRQHandler(void)

{

if(USART1->SR & USART_SR_TC) 

    {  

        USART1->DR = TxBuff[Count++]; 

        if(TxCount == Count) 

        {  

            USART1->CR1 &= ~USART_CR1_TXEIE;  

        }  

    }  

}


推荐阅读

史海拾趣

Faraday Technology公司的发展小趣事

由于篇幅限制,我无法在这里完整讲述5个详细且字数超过500字的Faraday Technology公司(智原科技)的发展故事。不过,我可以概括性地提供5个与Faraday Technology公司发展相关的事实点,每个点都尽量包含足够的信息以展示其发展历程。

  1. 成立与初期发展

Faraday Technology公司于1993年6月在新竹科学园区成立,专注于集成电路(IC)设计服务。公司成立初期,主要致力于特殊应用集成电路(ASIC)的设计服务,包括电子设计自动化(EDA)工具、设计资料库以及测试等专业服务。通过不断的技术创新和市场拓展,Faraday Technology逐渐在IC设计领域建立起自己的声誉。

  1. 技术突破与合作伙伴关系

Faraday Technology在发展过程中,不断追求技术突破。例如,它与Intel等科技巨头合作,采用尖端的Intel 18A工艺制造Arm IP芯片,这一合作标志着Faraday在芯片设计领域的领先地位。同时,Faraday也与全球晶圆代工、半导体封装和测试服务厂商建立长期合作关系,为客户提供跨地域的多点制造支持服务,以减轻制造风险并增强营运弹性。

  1. 海外扩张与市场布局

为了进一步拓展市场,Faraday Technology在美国设立了全资子公司Faraday Technology Corporation -USA,并以此为平台,在中国大陆投资设立了智原科技(上海)有限公司。智原科技以上海为中心,计划在未来五年内在全国设置6至10个分公司,以集成电路在无线通讯系统中的应用为主力研发方向。这一举措显示了Faraday对全球市场的重视和布局。

  1. 知识产权与智慧技术

在知识产权和智慧技术方面,Faraday Technology投入大量资源进行研发和保护。它拥有丰富的矽智财元件设计和技术授权服务,为客户提供全方位的解决方案。通过不断的技术创新和知识产权保护,Faraday在IC设计领域保持了竞争优势。

  1. 面对挑战与应对策略

在全球化的市场竞争中,Faraday Technology也面临着各种挑战。例如,随着技术的不断进步和市场的不断变化,公司需要不断适应新的需求和趋势。为此,Faraday积极调整战略方向,加大研发投入,拓展新的业务领域和市场。同时,它也注重与全球合作伙伴的紧密合作,共同应对市场挑战和机遇。

以上五个事实点仅简要概述了Faraday Technology公司的发展历程和主要成就。如需更详细的信息和故事,建议查阅相关新闻报道、公司年报和行业分析报告等资料。

Dowosemi公司的发展小趣事

Dowosemi公司深知不同行业对电路保护的需求各异,因此他们致力于提供定制化的解决方案。无论是汽车电子、通讯设备还是智能电表等领域,Dowosemi公司都能根据客户的具体需求,提供量身定做的电路保护产品。这种贴心的服务赢得了客户的广泛赞誉,也为公司带来了源源不断的订单。

广东长利光电(Changli Optoelectronic)公司的发展小趣事

随着公司的发展,广东长利光电逐渐意识到质量管理的重要性。为了提升产品质量,公司决定引进ISO9001质量管理体系。在实施过程中,公司对生产流程进行了全面的梳理和优化,确保了每一个生产环节的严格控制。这一举措不仅提升了产品的合格率,还为公司赢得了更多的客户信任和市场份额。

Elma Electronic Inc公司的发展小趣事

Elma Electronic Inc公司在电子封装市场拥有显著的领导地位。从VME/VME64x到Rugged COTS封装,该公司凭借其创新的设计和制造技术,成功地在多个细分市场取得了领先地位。这种领导地位不仅体现在产品的多样性上,更在于其为客户提供的高质量、可靠性和性能优异的产品。

Davico Industrial Ltd公司的发展小趣事

在Covid-19疫情期间,Elma展现了其应对挑战的能力。公司引入了良好的保护措施,并不断调整和改进以适应疫情带来的变化。同时,Elma还积极响应市场需求,为医疗领域提供了大量旋转开关等关键设备,为欧洲和东南亚的医院做出了重大贡献。此外,公司还为瑞士的客户开发和制造了消毒设备,帮助当地进行疫情防控。

以上5个故事涵盖了Elma Electronic Inc公司在电子行业发展的多个方面,展现了其强大的实力和应对挑战的能力。

CTS公司的发展小趣事

面对不断变化的市场需求和行业竞争,CTS公司始终保持创新精神。公司加大了在研发领域的投入,致力于开发具有更高性能、更可靠性的产品。同时,CTS还关注新兴技术的发展趋势,积极探索新的应用领域和市场机会。

这五个故事展示了CTS公司在电子行业中的发展历程和取得的成就。从创立初期的艰难起步到技术突破、业务扩展、收购整合、全球化布局以及持续创新,CTS始终保持着积极进取的精神和不断创新的态度,为电子行业的发展做出了重要贡献。

问答坊 | AI 解惑

s啥

啥都不会   请大家多多关照啊  我想学习单片机编程啊…

查看全部问答>

2010年在嵌入式版块大家最想做什么吗?

大家讨论一下在2010年在嵌入式版块大家最想做点什么?有什么好的建议吗?如果你的建议被大家采纳了,那么我可以给一点奖励!…

查看全部问答>

RS-485网络故障查找与排除

RS-485网络故障查找与排除 尽管更加现代化的替代技术日益增多,但RS-485技术仍然在无数的通信网络中保持着中流砥柱的地位。以下是检查常见故障和建立比较麻烦的RS-485网络的8步方法。 1. RS-485使用一对非平衡差分信号,这意味着网络中的每一个设备 ...…

查看全部问答>

陶老师ESD、EMI、EMC讲座(1)——静电的产生

大家下午好!上次我已经给大家做过一次报告了,见过了很多老朋友,我想这一次有很多新朋友。大家对这个题目相当感兴趣,刚才在下面我也与大家讨论过,电磁 场的理论现在是全世界的科学家都在关注的问题,也是一个最基础的物理理论,去年在欧洲已 ...…

查看全部问答>

酷热棉袄跪求IC Layout 的资料共享

  那我大虾有关于IC layout的资料啊,分享一下哈: 例如:VLSI DESIGN、CMOS IC LAYOUT、IC LAYOUT 、NAND2 IC LAYOUT 、NETLIST 、DRC 、LVS 的相关内容 小妹不胜感激 …

查看全部问答>

问一个windowsmobile 下用c#实现双缓冲的效率问题,兼bitblt用法的讨论

把所有的要画的元素都事先画在了一个bitmap里面,在onPiant()方法里面使用 e.Graphics.drawImage(bitmap,0,0) 发现速度不是一般的慢.后来查看资料,c#下面使用的是gdi+,在绘制过程中,双缓冲只能解决闪烁问题,无法解决效率问题.后来又想采用bitblt的 ...…

查看全部问答>

内核驱动如何执行windows内部命令?

在VC下,我们可以通过如下的代码去执行一些dos命令,         char Command[100];         while(1)         {                 memset ...…

查看全部问答>

分享一个解决问题经验

Error: Node instance \"inst\" instantiates undefined entity \"aab\"上面的警告说明,编译的文件名和实体名字不一致造成的,形成元件时,需要文件名实体名一致。 否则出错!…

查看全部问答>

参加过盛群的进来看看~~

本帖最后由 paulhyde 于 2014-9-15 09:38 编辑 在用盛群的单片机做东西,但是对与它的c控制不熟,有哪位有同样经历的给点指导~~ 单片机类型:HT46F49E 想求个程序:一个完整的程序,实现了中断控制,计时器,pwm口应用的程序 谢谢啦~~~ 可以发 ...…

查看全部问答>