将一个用for循环实现的流水灯C程序模块化

博客讲述了如何将一个C语言实现的流水灯程序进行模块化,特别是将延时函数delay_ms独立出来,通过创建delay.c和delay.h文件并添加到Keil项目中。接着,文章探讨了使用定时器替代延时函数以提高精度,详细介绍了C51单片机的定时器工作原理和相关寄存器,以及如何配置定时器以实现精确的1ms延时。
摘要由CSDN通过智能技术生成

1、原来所有的代码都被编写在一个.c文件中。创建keil project(89C52)并且仿真流水灯

一旦代码复杂,会很难修改。而且如果延时函数常用,也不方便移植。将延时函数模块化,可以使延时函数变得容易移植。

#include <reg52.h>
void delay_ms(unsigned int t);
unsigned char tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

void main(void)
{
	unsigned char i;

	while(1)
	{
		for(i=0;i<8;i++)
		{
			P2=tab[i];
			delay_ms(5000); 
		} 
	}
}

void delay_ms(unsigned int t)
{
	unsigned int x,y;
	for(x=t;x>0;x--)
	for(y=50;y>0;y--);
}

2、将延时子函数delay_ms模块化。创建delay.c 和 delay.h。delay.c 存放子函数,delay.h 存放函数声明。并且将delay.c 添加到项目工程中,以及指明delay.h的路径。
2.1 delay.h

以下是一个可能的分模块化的C语言程序: ```c // 定义LED控制引脚 #define LED_PORT P0 // 定义AT24C02的地址 #define AT24C02_ADDR 0xA0 // 定义AT24C02中的I/O口 #define IO_PORT P1 #define IO_PIN 0 // 定义LED灯的数量 #define LED_COUNT 8 // 定义计时器的计数值 #define TIMER_COUNT 1000 // 定义流水灯的控制变量 static uint8_t led_index = 0; // 定义计时器的计数变量 static uint16_t timer_count = 0; // 初始化LED和I/O口 void init_led_and_io() { LED_PORT = 0x00; IO_PORT &= ~(1 << IO_PIN); } // 初始化AT24C02 void init_at24c02() { // 初始化I2C总线 init_i2c(); // 等待AT24C02初始化完成 delay_ms(10); // 写入流水灯控制字节到AT24C02中 uint8_t data = LED_PATTERN; for (uint8_t i = 0; i < LED_COUNT; i++) { i2c_write_byte(AT24C02_ADDR, 0x40 + i, data); } } // 从AT24C02中读取流水灯控制字节 void read_led_pattern() { for (uint8_t i = 0; i < LED_COUNT; i++) { LED_PATTERN |= (i2c_read_byte(AT24C02_ADDR, 0x40 + i) << i); } } // 控制LED流水灯 void control_led() { // 控制LED点亮 LED_PORT = ~(1 << led_index); // 控制I/O口输出 if (LED_PATTERN & (1 << led_index)) { IO_PORT |= (1 << IO_PIN); } else { IO_PORT &= ~(1 << IO_PIN); } // 更新LED索引 led_index = (led_index + 1) % LED_COUNT; } // 延时函数,使用定时器实现 void delay() { // 等待计时器溢出 while (timer_count < TIMER_COUNT); // 重置计时器 timer_count = 0; } // 定时器中断处理函数 void timer_isr() { // 增加计时器计数值 timer_count++; } // 主函数 int main() { // 初始化LED和I/O口 init_led_and_io(); // 初始化AT24C02 init_at24c02(); // 从AT24C02中读取流水灯控制字节 read_led_pattern(); // 初始化定时器 init_timer(); // 启用定时器中断 enable_timer_isr(); // 主循环 while (1) { // 控制LED流水灯 control_led(); // 延时1s delay(); } return 0; } ``` 在这个程序中,LED的控制引脚和AT24C02的地址通过宏定义来定义。 程序中使用一个静态变量 `led_index` 来记录LED流水灯的状态,使用一个静态变量 `timer_count` 来记录计时器的计数值。 程序中使用了四个函数:`init_led_and_io()` 初始化LED和I/O口,`init_at24c02()` 初始化AT24C02,`read_led_pattern()` 从AT24C02中读取流水灯控制字节,`control_led()` 控制LED流水灯,`delay()` 延时函数。其中 `delay()` 函数使用定时器来实现延时。 程序中还使用了一个定时器中断处理函数 `timer_isr()` 来处理定时器中断。在 `main()` 函数中,程序首先初始化LED和I/O口,然后初始化AT24C02,并从AT24C02中读取流水灯控制字节。接着,程序初始化定时器,并启用定时器中断。最后,程序进入主循环,不断控制LED流水灯并延时1s。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值