51单片机c语言编程100例(51单片机c语言编程实例详解)
作者: 双枪 2023-08-17 12:40:19
51单片机c语言编程实例详解
入门篇
本篇将通过一些简单的实例来介绍51单片机的基本编程方法。
第一例:LED流水灯
这是入门级的实例,可以帮助我们了解51单片机的I/O口和基本控制语句的使用。我们使用P0口上的4个LED灯,让它们依次亮起,再逐个熄灭,不断循环。
``` c
#include
void delay(int i) // 延迟函数
{
while(i--);
}
void main()
{
while(1)
{
int i;
for(i=0;i<4;i++) // 依次点亮每个LED
{
P0 = ~(0x01 << i); // P0口输出
delay(20000); // 延迟约100ms
P0 = 0xFF; // 熄灭
}
}
}
```
第二例:LCD显示字符串
LCD是一个很常用的外设,可以将ASCII码显示出来。下面这个实例是将字符串\"Hello World!\"显示在LCD上。
``` c
#include
#include
#define LCD_data P1
sbit RS = P3^5;
sbit RW = P3^6;
sbit E = P3^4;
void LCD_init() // LCD初始化函数
{
delay_100us(15);
LCD_command(0x30);
delay_100us(5);
LCD_command(0x30);
delay_100us(1);
LCD_command(0x30);
delay_100us(1);
LCD_command(0x38); // 8位数据总线,两行8x16字库点阵
LCD_command(0x08); // 关闭显示
LCD_command(0x01); // 显示清屏
LCD_command(0x06); // 光标自动右移,不移动屏幕
LCD_command(0x0C); // 打开显示,光标关闭
}
void LCD_command(char cmd) // 发送指令
{
RW = 0;
RS = 0;
LCD_data = cmd;
E = 1;
_nop_();
E = 0;
delay_100us(2);
}
void LCD_write(char dat) // 发送数据
{
RW = 0;
RS = 1;
LCD_data = dat;
E = 1;
_nop_();
E = 0;
delay_100us(2);
}
void main()
{
LCD_init(); // 初始化LCD
LCD_command(0x80);
int i;
char mystr[] = \"Hello World!\";
for(i=0;i<12;i++)
{
LCD_write(mystr[i]); // 将字符串依次显示
}
}
```
应用篇
本篇将通过一些实用的例子来介绍51单片机的应用。
第三例:小车控制
通过控制两个电机的转速和方向,以控制小车的运动。
``` c
#include
sbit Motor1_in1 = P1^0;
sbit Motor1_in2 = P1^1;
sbit Motor2_in1 = P1^2;
sbit Motor2_in2 = P1^3;
void delay_ms(int i) // 延迟函数
{
while(i--)
{
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x18;
TR0 = 1;
while(TF0 == 0);
TR0 = 0;
TF0 = 0;
}
}
void Motor1(int speed, char dir) // 控制电机1
{
if(dir == 'F') // 向前
{
Motor1_in1 = 0;
Motor1_in2 = 1;
}
else if(dir == 'B') // 向后
{
Motor1_in1 = 1;
Motor1_in2 = 0;
}
else // 停止
{
Motor1_in1 = 0;
Motor1_in2 = 0;
}
P2 = speed;
}
void Motor2(int speed, char dir) // 控制电机2
{
if(dir == 'F')
{
Motor2_in1 = 0;
Motor2_in2 = 1;
}
else if(dir == 'B')
{
Motor2_in1 = 1;
Motor2_in2 = 0;
}
else
{
Motor2_in1 = 0;
Motor2_in2 = 0;
}
P3 = speed;
}
void main()
{
while(1)
{
Motor1(100, 'F'); // 两个电机向前转
Motor2(100, 'F');
delay_ms(1000); // 延迟1s
Motor1(50, 'B'); // 电机1向后转,电机2不动
delay_ms(1000);
Motor1(0, 'S'); // 电机停止
Motor2(0, 'S');
delay_ms(1000);
}
}
```
第四例:温湿度检测
通过读取DHT11传感器的数据,可以检测室内的温度和湿度。
``` c
#include
sbit DHT11 = P1^0;
void delay_us(unsigned int i) // 微秒级延迟
{
while(i--);
}
void delay_ms(unsigned int i) // 毫秒级延迟
{
while(i--)
{
delay_us(1000);
}
}
void start_DHT11() // 启动传感器
{
DHT11 = 0; // 主机发起Start信号
delay_ms(20);
DHT11 = 1; // 延时18~20us
delay_us(30);
while(DHT11 == 1); // 传感器返回Response信号
while(DHT11 == 0);
while(DHT11 == 1); // 传感器发送数据
}
int read_DHT11() // 读取传感器数据
{
int i, j, k;
int value = 0;
for(i=0;i<8;i++)
{
while(DHT11 == 0); // 信号起始位
delay_us(30);
k = 0;
for(j=0;j<8;j++)
{
if(DHT11 == 1)
{
k++;
delay_us(1);
}
else
{
delay_us(30);
}
}
if(k > 4) // 1的数据
{
value |= (1<<(7-i)); // 改写变量
}
}
return value;
}
void main()
{
int temp, hum;
while(1)
{
start_DHT11(); // 启动传感器
if(DHT11 == 0) // 检测响应是否正常
{
delay_us(80);
if(DHT11 == 1) // 读取数据长度
{
temp = read_DHT11(); // 读取温度数据
hum = read_DHT11(); // 读取湿度数据
}
}
P0 = temp;
P1 = hum; // 将数据输出到LED显示屏
delay_ms(1000);
}
}
```
拓展篇
本篇将通过一些拓展的例子来介绍51单片机的高级应用。
第五例:实现PWM波
通过编程产生脉冲宽度可变的PWM波。这是在工程设计中非常常用的一种技巧。
``` c
#include
sbit Button = P1^0;
sbit LED = P1^1;
void init_timer0()
{
TMOD |= 0x01; // 在定时器0中工作方式1
TH0 = 0x0B; // 预置计时器初值
TL0 = 0xFC;
ET0 = 1; // 启动定时器0
EA = 1;
TR0 = 1;
}
void main()
{
Button = 1;
init_timer0();
while(1)
{
if(Button==0)
{
LED = 1;
delay_ms(18);
LED = 0;
delay_ms(2);
}
}
}
void timer0() interrupt 1
{
static int count = 0;
TH0 = 0x0B;
TL0 = 0xFC;
count++;
if(count <= 10) // 比较脉冲宽度与10ms
{
LED = 1;
}
else if(count <= 100)
{
LED = 0;
}
else
{
count = 0;
}
}
```
第六例:IIC总线通信
通过I2C总线协议实现51单片机与其他设备的通信,可以方便地控制其他设备并读取它们的数据。
``` c
#include
sbit SDA = P2^0;
sbit SCL = P2^1;
void start_IIC() // 启动通信
{
SDA = 1;
SCL = 1;
delay_us(10);
SDA = 0;
delay_us(10);
SCL = 0;
}
void stop_IIC() // 关闭通信
{
SCL=0;
delay_us(10);
SDA=0;
delay_us(10);
SCL=1;
delay_us(10);
SDA=1;
delay_us(10);
}
unsigned char read_byte() // 读取一个字节
{
unsigned char i, dat;
SDA=1;
dat=0;
for(i=0;i<8;i++)
{
SCL=0;
delay_us(10);
SCL=1;
delay_us(10);
if(SDA)
{
dat |= 1;
}
else
{
dat &= ~1;
}
if(i<7) // 收到读取标识,继续读取
{
dat <<= 1;
}
}
return dat;
}
void write_byte(unsigned char dat) // 发送一个字节
{
unsigned char i;
for(i=0;i<8;i++)
{
if(dat & 0x80)
{
SDA=1;
}
else
{
SDA=0;
}
delay_us(10);
SCL=1;
delay_us(10);
SCL=0;
dat <<= 1;
}
}
void check_ack() // 检测应答
{
SDA = 1;
delay_us(10);
SCL = 1;
while(SDA == 1);
SCL = 0;
}
void read_Dev(unsigned char dev1, unsigned char *p_dat) // 读取设备信息
{
start_IIC(); // 启动通信
write_byte(0xD0);
check_ack(); // 检测应答
write_byte(dev1);
check_ack(); // 发送设备地址
start_IIC();
write_byte(0xD1);
check_ack(); // 检测应答
*p_dat = read_byte(); //读取设备数据
stop_IIC();
}
void main()
{
unsigned char dat;
read_Dev(0xB4, &dat); // 读取设备数据
P0 = dat; // 输出到LED显示屏
}
```
以上是51单片机c语言编程100例的部分实例,希望对大家学习51单片机编程有所帮助。