我在学习单片机的过程中懵懵懂懂地学了半桶水,以上几种单片机都学过一点,但是都不是很精,最近想把自己学过的知识梳理一遍,所以就做了这个笔记。
学习单片机有句话叫“万物之初在于点灯”(谁说的?不知道,可能是鲁迅∩0∩),所以我在这篇笔记里比较一下这三种单片机的4种点灯方式。
1、51单片机的点灯方式:
我用的51单片机是AT89S52,51单片机的设置和电路接线非常简单。这也是51比较好学的原因。
#include while(1) D1=0; } } void delay(unsigned int z) //延迟函数 { unsigned int i,j; for(i=0;i } 2、arduino的点灯方式: 我用的是arduino uno的板子,arduino的设置和接线都相当简单,这正是电子爱好者最容易上手arduino的原因。 /* LED闪烁程序 */ // 大多数Arduino板的Pin 13会连接一个LED int LED = 13; void setup() { // 将LED代表的13pin脚定义为输出 pinMode(LED, OUTPUT); } void loop() { digitalWrite(LED, HIGH); //开灯 delay(1000); // 等1秒 digitalWrite(LED, LOW); // 关灯 delay(1000); // 等1秒 } 3、STM8的两种点灯代码。 STM8和STM32有两种编码方式:库函数模式和寄存器模式。寄存器模式与51单片机的编码方式类似,即通过设置寄存器来控制IO口输入输出;库函数模式则是通过调用官方提供的标准固件库,来实现对IO口的控制。 固件库可以这么理解,官方按照一定的标准格式,将寄存器的设置封装在固件库里,我们应用时,可以不用去记繁杂的各种寄存器设置方法,只要应用官方提供的固件库标准接口函数即可实现对单片机的控制。 库函数模式虽然不可避免地增加了代码长度和一定的复杂度,但是从编程方式的简易化、代码的可读性和通用性以及复杂工程的系统化等方面有极其明显的优势。 但是寄存器模式也有它自己的优势,代码短,结构简单,执行效率高,在一些对系统资源比较紧张的工程中比较适用。 (1)库函数版本: 首先是建立一个工程,建立STM8工程的方法可以参考我前一个笔记。 如下图所示: 其中“Driver”文件夹下的“led.c”文件是用户,也就是我们自己编写的驱动文件。用户在使用中,只需要编写“led.c”驱动文件和“main.c”主函数就好了。 整个工程项目加入分层的思想,将对以后的移植非常有利。打个比方:底层和应用层隔离。底层驱动与应用层无关,“main.c”函数在“led.c”驱动文件中已经写好,这些才与硬件有关,这样需要移植到不同硬件时,“main.c”主函数可以不做任何修改,只需要修改和底层相关的“led.c”驱动。 下面是“led.c”驱动程序示范。 #include "led.h" void LED_Init(void) { GPIO_Init(LED1_PORT,LED1_PIN,GPIO_MODE_OUT_PP_HIGH_FAST ); //定义LED的管脚的模式 } void LED1_Open(void) { GPIO_WriteLow(LED1_PORT,LED1_PIN);//打开LED } void LED1_Close(void) { GPIO_WriteHigh(LED1_PORT,LED1_PIN);//关掉LED } void LED1_Toggle(void) { GPIO_WriteReverse(LED1_PORT,LED1_PIN);//翻转LED状态 } 注:GPIO的输入输出和管脚模式设置准备在另一个笔记里详述,此处不详细展开。 这里还要注意的是“led.h”,这个文件定义了操作硬件哪个具体的pin脚。如下面程序: #ifndef __LED_H #define __LED_H #include "stm8s_gpio.h" #define LED1_PIN GPIO_PIN_5 #define LED1_PORT GPIOB void LED_Init(void); void LED1_Open(void); void LED1_Close(void); void LED1_Toggle(void); #endif 在这个头文件里,我们定义了LED1对应的是芯片的PB5脚,这跟我用来测试的stm8s103f3最小系统板的设置是符合的,PB5脚接了一个测试用的LED。 所以以后要使用更多的pin脚来控制LED灯或pin脚输出,可以按以上“led.c”和“led.h”的形式来编写驱动程序。 然后就是“main.c”主程序: #include "stm8s.h" #include "stm8s_clk.h" #include "led.h" void delay() //延迟函数 { int i,j; for(i=0;i<1000;i++) { for(j=0;j<1000;j++); } } int main(void) { /*设置内部高速时钟16M为主时钟*/ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); LED_Init(); //LED驱动程序初始化 LED1_Close(); //关闭LED1 while(1) { LED1_Toggle(); // LED1状态翻转 delay(); //延迟函数 } } 主函数没什么太多好讲的,基本上思路跟前面51和arduino是一样的。在实践过程中我碰到过两个问题,一个是时钟设置的问题,另一个是由于ASSERT报错的问题。这两个问题我准备都另外写文说明一下,这里就不重复了。 (1)寄存器版本: 寄存器版本的程序简单了,有多种写法,下面是我写的一个例子: #include "stm8s.h" #include "stm8s_clk.h" void delay() { int i,j; for(i=0;i<1000;i++) { for(j=0;j<1000;j++); } } int main(void) { /*设置内部高速时钟16M为主时钟*/ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); GPIOB->DDR = 0x20;//配置GPIOB的方向寄存器,设置pin5为输出模式 GPIOB->CR1 = 0x20;//配置GPIOB_5为推挽输出 GPIOB->CR2 = 0x00; while(1) { GPIOB->DDR = 0x20;//GPIOB_5输出高电平,亮 delay(); GPIOB->DDR = 0x00;//GPIOB_5输出低电平,暗 delay(); } } STM8的GPIO寄存器配置可以参考下表。
sbit LED1=P1^0; //P1口0 pin接LED,并在程序里定义
void delay(unsigned int z);
void main()
{
{
delay(100);
D1=1;
delay(100);
上一篇:STM8学习笔记三——错误:no definition for "assert_failed"
下一篇:IAR for STM8学习笔记(一)建立工程
推荐阅读最新更新时间:2024-11-24 16:16
设计资源 培训 开发板 精华推荐
- #第五届立创电子设计大赛#白灼半夏
- [新丐中丐]IP6505降压快充模块
- LT3091HR 产生极低输出电压的典型应用
- 2.52W、10-LED 通用 LED 照明驱动器
- AM2F-2415SZ 15V 2 瓦 DC/DC 转换器的典型应用
- 使用 Microchip Technology 的 MICRF001 的参考设计
- AD8230EVAL,评估板采用 AD8230 低漂移、差分采样、精密仪表放大器
- icebreaker++ :icebreaker FPGA 板,升级了 ECP5
- 使用 Sanken Electric Co., Ltd 的 STR2000 的参考设计
- 用于服务器的 3.3V DC 到 DC 单路输出电源