首页 >> 大全

寄存器方式点亮LED

2023-11-27 大全 26 作者:考证青年

寄存器方式点亮LED

文章目录 4、总结

前言

这个实验使用的处理器是,听说初学单片机的时候建学寄存器,于是我就用了这个核心板进行学习,之前有接触过STC51单片机,新建寄存器的工程比较简单,像51工程那样几个文件就好了。点亮LED主要是学习GPIO作为输出功能使用、寄存器及单片机的时钟系统。

1、新建MDK工程

1.1 点击 -> New …

1.2 在电脑合适的位置新建一个存放工程的文件夹,并对该文件夹进行命名,然后把工程文件都放到这个文件夹里面再对工程命名。

1.3 建好后会提示要添加对应芯片型号,这里选,也可以在输入框搜索芯片,这里如果没有得选,则说明安装pack芯片支持包(Keil..1.0.5.pack)不成功导致的。

有的时候会提示下面这个对话框,如果已经安装了PACK包,可以直接叉掉即可。

1.4 新建一个空白文本文档,保存为main.c文件。

1.5 鼠标右键 点击Add Files to Group…,添加刚才新建的main.c文件到工程分组里。

1.6 新建完的工程如下图:

1.7 写完代码编译之前勾选输出HEX文件,如果不勾选则无法输出下载文件。

1.8 最终写完代码编译发现最终会有一个报错提示如下:

原因就是没有添加对应的.s启动文件,去网上找了一个启动文件添加到工程就行。

启动文件下载路径:

鼠标右键 点击Add Files to Group…,添加.s文件到工程分组里,如下图:

查看芯片数据手册可以知道C8T6的flash是64k的,所以要用中容量的启动文件。

查阅中文参考手册得知下面的数据:

小容量: FLASH ≤ 32K

中容量: 64K ≤ FLASH ≤ 128K

大容量: 256K ≤ FLASH

ld:低密度产品,FLASH小于64K是小容量

md:中等密度产品,FLASH=64 or 128是中容量

hd:高密度产品,FLASH大于128 是大容量

综上描述,这里选择的是 .s 作为启动文件。

1.9 发现了添加了还是会报错,于是就去看了下正点原子的开发指南新建工程章节,发现这个103的寄存器是要适当修改这个启动文件内容的。具体是 函数,该函数修改后代码如下:

要把132到134行代码屏蔽或者删掉才可以,因为没有用到 函数,所以注释掉

如果是库函数版本的工程,可以忽略这个步骤。

2、硬件连接

LED连接到芯片的PC13引脚上,一端接到了VCC,所以需要低电平才能点亮LED,高电平熄灭。

板子正面图:

3、查看手册&编写程序 3.1 查看手册配置

参考手册:中文参考手册.pdf、芯片数据手册.pdf

3.1.1 查看总线架构,得知LED(GPIOC)挂载在总线在APB2上。

3.1.2 查看获取挂载在APB2的GPIOC端口及RCC的基地址。

RCC:

GPIOC:

3.1.3 端口配置寄存器,由于LED所在的端口是PC13,所以用的寄存器是(5处有说明)

采用推挽输出模式,速度50M,那么bit23-20对应的值就要设置为0011即对应十进制为3。

3.1.4 获取APB2总线的偏移地址为:0x18,时钟需要使能第四个位。

3.1.5 配置端口输出数据寄存器,操作bit13,偏移地址:0x0C

3.2 程序编写 3.2.1 点亮LED

/* 使能端口时钟,设置第4位为1为使能 */
从前面可以获取到RCC的基地址和APB2的偏移地址,两者加起来就是这个地址了
(*(volatile int *)0x40021018) |= 1<<4;/* 配置输出模式 */
首先把整个端口清零,以免有误操作,之后再设置这个端口对应的IO口的值为3(不采用直接给端口赋值的方式,采样位移方法直观高效)
(*(volatile int *)0x40011004) &= ~(0x0F<<20);
(*(volatile int *)0x40011004) |= 3<<20;/* 配置端口输出功能,输出低电平就可以点亮LED了(采取清零操作) */
(*(volatile int *)0x4001100C) &= ~(1<<13);

这里为什么要用 这个关键字修饰就不详细描述了,可以网上看看教程。

整理代码如下:

int main(void)
{/* 使能端口时钟 */(*(volatile int *)0x40021018) |= 1<<4;/* 配置输出模式 */(*(volatile int *)0x40011004) &= ~(0x0F<<20);//清0(*(volatile int *)0x40011004) |= 3<<20;		 //置1/* 配置端口输出功能,输出低电平 */(*(volatile int *)0x4001100C) &= ~(1<<13);while(1);
}

为了方便直观看代码,可以采取宏定义的方法来修改,更加直观可见

整理代码如下:

#define RCC_APB2ENR (*(volatile int *)0x40021018)
#define GPIOC_CRH   (*(volatile int *)0x40011004)
#define GPIOC_ODR   (*(volatile int *)0x4001100C)int main(void)
{/* 使能端口时钟 */RCC_APB2ENR |= 1<<4;/* 配置输出模式 */GPIOC_CRH &= ~(0x0F<<20);GPIOC_CRH |= 3<<20;/* 配置端口输出功能,输出低电平 */GPIOC_ODR &= ~(1<<13);while(1);
}

上面几行代码就可以简单点亮一个LED了。

3.2.2 LED闪烁

想要LED实现闪烁效果,可以在点亮和熄灭之间添加延时间隔就可以清晰看到闪烁效果了。

简单写个for循环就可以达到延时功能。

整理代码如下:

#define RCC_APB2ENR (*(volatile int *)0x40021018)
#define GPIOC_CRH   (*(volatile int *)0x40011004)
#define GPIOC_ODR   (*(volatile int *)0x4001100C)void Delay_ms(volatile int t);int main(void)
{/* 使能端口时钟 */RCC_APB2ENR |= 1<<4;/* 配置输出模式 */GPIOC_CRH &= ~(0x0F<<20);GPIOC_CRH |= 3<<20;/* 配置端口输出功能,输出低电平 *///GPIOC_ODR &= ~(1<<13);//GPIOC_ODR |= (1<<13);while(1){GPIOC_ODR &= ~(1<<13);//输出低电平Delay_ms(1000000);GPIOC_ODR |= (1<<13);//输出高电平Delay_ms(1000000);}
}void Delay_ms(volatile int t)
{int i;while(t--)for(i=0;i<800;i++);
}

4、总结

通过这个寄存器的学习,使我学会了查阅芯片的使用手册及如何操作寄存器从而达到操作GPIO的效果,另外也加固了对C语言的学习,比如位操作、关键字在这里的用法作用等。

实验效果

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了