当前位置:网站首页>STM8S103f单片机的开发(1)LED灯的点亮
STM8S103f单片机的开发(1)LED灯的点亮
2022-06-10 14:11:00 【是阿蛋啊】
第一章 STM8S103f单片机开发之LED灯的点亮
前言
谁能想到光电专业的学生要学习那么多那么多的不同的课,最近(其实也有一段时间了)我们学习了嵌入式,虽然老师天天说这个简单,给一些一二年级的小学生学几天,他们也搞的很好,但是真正上手才知道,开始学习的阶段还是有些难度的。
一、目标任务
完成单片机STM8S103f上LED灯点亮,这里我准备采取2个方式来,(1)就是指定端口控制高低电平点亮LED,也是最基础的,(2)采用按键输入,LED灯输出的方式来点亮LED
二、任务步骤
1.查看引脚
这个是第一步,也是最基础的一步,只要不那么粗心就没有问题,就是看一下电路图。

像这个就是LED灯的引脚,灯一的引脚就是PD2,灯二就PC7,以此类推。除了LED外,我们还需要KEY按键的引脚,在任务2和任务3中需要用到。

2.任务一
包含头文件这个是必要的,学过C语言的都知道,像我们学习的这个板子,编写程序在顶端得加上这个命令。
#include<iostm8s103f3.h>我们要宏定义各个灯的开光控制,例如
#define LED1_ON() PD_ODR_bit.ODR2 = 0
#define LED2_ON() PC_ODR_bit.ODR7 = 0
#define LED3_ON() PC_ODR_bit.ODR6 = 0
#define LED4_ON() PC_ODR_bit.ODR3 = 0
#define LED1_OFF() PD_ODR_bit.ODR2 = 1
#define LED2_OFF() PC_ODR_bit.ODR7 = 1
#define LED3_OFF() PC_ODR_bit.ODR6 = 1
#define LED4_OFF() PC_ODR_bit.ODR3 = 1LED1_ON()就是给LED1所在引脚一个低电平,点亮LED1,PD和最后的2指这个命令的对象是PD2引脚,ODR表示输出模式下写入寄存器的数值通过锁存器加到相应的引脚上(也就是PD2),bit表示位数,ODR2表示这个引脚在ODR输出寄存器的第3位。
OFF宏定义与ON差不多,给目标引脚一个高电平,使得LED灯熄灭。
我们需要什么引脚,就需要将这些引脚进行一个初始化操作,编写对应的初始化函数。
void LED_Init()
{
PD_DDR_bit.DDR2 = 1;
PD_CR1_bit.C12 = 1;
PD_CR2_bit.C22 = 1;
PC_DDR_bit.DDR7 = 1;
PC_CR1_bit.C17 = 1;
PC_CR2_bit.C27 = 1;
PC_DDR_bit.DDR6 = 1;
PC_CR1_bit.C16 = 1;
PC_CR2_bit.C26 = 1;
PC_DDR_bit.DDR3 = 1;
PC_CR1_bit.C13 = 1;
PC_CR2_bit.C23 = 1;
}viod LED_Init()就是定义一个叫LED_Init的函数,函数的第一句和宏定义OFF好像有几分相似,但是它们表达的意思很不同。
DDR是数据方向寄存器,PD_DDR_bit.DDR2 表示PD2这个引脚的数据方向寄存器,有2个方向可以选择,如果想这个成为输出端,就置1,成为输入端,就置0,很明显,我们这里是要把LED灯作为输出端口,所有要把四个LED灯的引脚的ODR寄存器置1。
CR2是端口控制寄存器1,PD_CR1_bit.C12表示PD2这个引脚的端口控制寄存器1,它在不同的DDR下有不同的选择模式,在DDR置1的情况下,CR1是输出模式选择器,CR1置0就是模拟开漏输出,置1就是推挽输出。
CR2是端口控制寄存器2,PD_CR1_bit.C12表示PD2这个引脚的端口控制寄存器2,和1一样有不同的选择模式,在DDR置一的情况下,CR2是输出速度选择器,CR2置0,输出速度最大为2MHZ,置1,输出速度最大为10MHZ。
所以3句在一起就,让LED灯引脚作为输出端,并且输出方式为最大10MHZ的推挽输出。
初始化函数写完,我们就可以开始编写主函数了。
int main(void)
{
CLK_CKDIVR = 0x00;
LED_Init();
while(1)
{
LED1_OFF();
delay(1000);
LED2_OFF();
delay(1000);
LED2_ON();
LED3_OFF();
delay(1000);
LED3_ON();
delay(1000);
LED4_OFF();
delay(1000);
LED2_OFF();
LED4_ON();
delay(1000);
}
}CLK_CKDIVR是一个时钟初始化函数,这里不细讲,我们只需要知道它选择了整个系统为1分频。
主函数里申用LED_Init(),将LED灯都完成初始化。
在while死循环里申用LED的开关命令,有一个小小的提醒,LED灯一开始就是开着的。烧录程序之后,看到的现象为LED1灭-LED2灭-LED2亮-LED3灭-LED3亮-LED4灭-LED2灭/LED4亮
主函数里还有一个delay函数,就是一个延时函数,目的是防止LED灯亮灭时间间隔太快,看不清楚现象。
void delay(unsigned int ms)
{
unsigned int x,y;
for(x = ms;x>0;x--)
for(y = 1000;y>0;y--);
}3.任务二
用按键输入来控制LED灯,只要在任务一的基础上进行一些删减即可
首先,将任务一中的宏定义删除,我们在任务二中已经有了按键的输入来改变状态,这里需要的就是编辑按键的初始化函数。
void KEY_Init()
{
PA_DDR_bit.DDR3 = 0;
PA_CR1_bit.C13 = 1;
PA_CR2_bit.C23 = 0;
PD_DDR_bit.DDR3 = 0;
PD_CR1_bit.C13 = 1;
PD_CR2_bit.C23 = 0;
PC_DDR_bit.DDR5 = 0;
PC_CR1_bit.C15 = 1;
PC_CR2_bit.C25 = 0;
}这里的按键引脚的PDR寄存器置0,表示这个引脚的数据方向是输入。在DDR置0,也就是引脚输入的情况下,CR1置1表示上拉输出,置0表示浮空输出,观察按键的电路图,显然这里要选择上拉输出。输入模式下的CR2置0表示禁止外部中断,置1表示允许外部中断,这里用不到外部中断,置0即可。所以3句话的意思,就是将按键所对应的引脚设定为上拉输入的输入端,并且禁止外部中断(不设置KEY初始化函数其实也行,不过这样规范一些)。
在主函数里,我们要用按键状态的变化来作为输入数据,进而改变LED灯的状态。
int main(void)
{
CLK_CKDIVR = 0x00;
LED_Init();
KEY_Init();
while(1)
{
if(PA_IDR_bit.IDR3==0)
{
delay(100);
if(PA_IDR_bit.IDR3==1)
{
delay(100);
PD_ODR ^= 0x04;
PC_ODR ^= 0x40;
}
}
if(PD_IDR_bit.IDR3==0)
{
delay(100);
if(PD_IDR_bit.IDR3==1)
{
delay(100);
PC_ODR ^= 0x80;
PC_ODR ^= 0x08;
}
}
if(PC_IDR_bit.IDR5==0)
{
delay(100);
if(PD_IDR_bit.IDR5==1)
{
delay(100);
PD_ODR ^= 0x04;
PC_ODR ^= 0x40;
PC_ODR ^= 0x80;
PC_ODR ^= 0x08;
}
}
}
}在while循环里,我所编辑的是一个if语句,if里的PA_IDR_bit.IDR3==0,IDR是输出寄存器的一种,不论引脚是输入还是输出模式,都可以通过该寄存器读入引脚状态值他,这个寄存器为只读寄存器。这句话的意思是,如果PA3(按键1)被按下,下一个则是,如果PA3被松开,中间加了一个delay函数来延时,在按键1被按下又弹起后,将对应LED灯引脚状态置反。
PD_ODR ^= 0x04,0x04是16进制,换算成二进制就是100,查看ODR寄存器表

100,1对应的就是ODR2,所以对应的引脚是PD2(LED灯1),将它的状态置反,在循环就是一直以固定的频率闪光。
总结
以上就是LED的一个基本的点亮,还有一些其他方式来点亮LED灯,像中断改变状态和调用库函数(库函数的工程配置不一样),再以后可能也会提到。
边栏推荐
- [vue/js] realize local caching of variables and objects through localstorage browser (text + full source code)
- [technical analysis] discuss the production process and technology of big world games - preliminary process
- 22.6.7成功使用doc2vec模型生成嵌入向量
- 【C语言】指针函数与函数指针、数组函数
- C multithreading learning note 4
- Main features of IIC bus / communication process / read / write process
- 单例模式和特殊类设计
- 【解决】每次加载已经训练好的模型,生成的向量会有不同
- About native SQL and database methods in PHP framework
- [original] poi 5 X xssf and HSSF use custom font colors
猜你喜欢

【解决】每次加载已经训练好的模型,生成的向量会有不同
![[big guy show] aiops in the eyes of Borui data, choosing the right track and the right people](/img/ea/740b877b5330a42065b5c5df0d9888.jpg)
[big guy show] aiops in the eyes of Borui data, choosing the right track and the right people

【专题介绍】圆桌论坛——AI与音视频技术的融合之路

【笔记】74HC573的一些记录

解决安装gerapy的时候报错:ERROR: Cannot uninstall ‘certifi‘. It is a distutils installed project...

Gin blog 总结1

短文本重复率快速检测

What is CAS and ABA in CAS

《软件体系结构原理、方法与实践》第二版期末考试复习总结

初学者自己搭建博客的设计工具和技巧
随机推荐
Simulated 100 questions and online simulated examination for safety production management personnel of hazardous chemical production units in 2022
P3379 [template] nearest common ancestor (LCA)
Flutter Wrap Button bottomNavigationBar学习总结4
五角大楼首次承认资助46个乌生物设施 俄方曾曝只有3个安全
还在说大学排名是笑话?最新规定:世界top50大学可以直接落户上海!
Bottomnavigationview is used in conjunction with viewpager, to modify icon size, to remove text, etc
22.6.7 successfully use doc2vec model to generate embedded vectors
【大咖秀】博睿数据眼中的AIOps,选择正确的赛道正确的人
[discrete mathematics review series] i. propositional logic
P3379 【模板】最近公共祖先(LCA)
2022 examination question bank and online simulation examination for main principals of hazardous chemical business units
Is it safe to open an account in qiniu
这些难搞的内存问题你都懂了吗?
[Discrete Mathematical period Review Series] Second and first order Logic (precate Logic)
2022危险化学品经营单位主要负责人考试题库及在线模拟考试
Binary tree and Figure 2
Redis基本使用1
短文本重复率快速检测
Kotlin 冒泡算法 ,高德地图 过滤掉两点之间距离小于50的数据,不重复显示
SIGIR 2022 | HKU and Wuhan University put forward kgcl: a recommendation system based on knowledge map comparative learning