STC芯片常用代码
提供STC芯片的示例代码和常用功能实现,方便开发者参考和使用
GPIO操作
LED闪烁
控制LED灯的闪烁,是最基础的GPIO操作示例。
LED闪烁代码
#include <STC89C52.h>
// 延时函数
void delay(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void main() {
// 设置P1.0为输出
P1 = 0xFF; // 初始化P1口
while (1) {
P1 &= ~0x01; // 点亮LED
delay(500); // 延时500ms
P1 |= 0x01; // 熄灭LED
delay(500); // 延时500ms
}
}
代码特点:
- 简单易懂,适合入门学习
- 包含基本的延时函数实现
- 演示了GPIO的输出操作
使用场景:
LED指示灯、状态指示、系统运行状态显示
按键检测
检测按键的按下和释放,实现按键输入功能。
按键检测代码
#include <STC89C52.h>
// 延时函数
void delay(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void main() {
// 设置P1.0为输出(LED),P3.2为输入(按键)
P1 = 0xFF;
P3 = 0xFF;
while (1) {
if (!(P3 & 0x04)) { // 检测按键是否按下
delay(10); // 消抖
if (!(P3 & 0x04)) { // 再次检测
P1 &= ~0x01; // 点亮LED
while (!(P3 & 0x04)); // 等待按键释放
P1 |= 0x01; // 熄灭LED
}
}
}
}
代码特点:
- 包含按键消抖处理
- 演示了GPIO的输入操作
- 实现了按键状态的检测
使用场景:
用户输入、功能切换、参数调整
串口通信
串口发送
通过串口发送数据,实现与上位机的通信。
串口发送代码
#include <STC89C52.h>
// 串口初始化
void UART_Init() {
SCON = 0x50; // 设置为模式1(8位UART)
TMOD = 0x20; // 设置定时器1为模式2(自动重装载)
TH1 = 0xFD; // 波特率9600,晶振11.0592MHz
TL1 = 0xFD;
TR1 = 1; // 启动定时器1
EA = 1; // 开启总中断
}
// 发送单个字符
void UART_SendChar(unsigned char c) {
SBUF = c;
while (!TI); // 等待发送完成
TI = 0; // 清除发送标志
}
// 发送字符串
void UART_SendString(unsigned char *str) {
while (*str) {
UART_SendChar(*str++);
}
}
void main() {
UART_Init();
while (1) {
UART_SendString("Hello STC!\r\n");
// 延时
unsigned int i, j;
for (i = 1000; i > 0; i--)
for (j = 110; j > 0; j--);
}
}
代码特点:
- 包含串口初始化配置
- 实现了单个字符和字符串的发送
- 波特率设置为9600,适用于大多数场景
使用场景:
数据上传、调试信息输出、与上位机通信
串口接收
通过串口接收数据,实现与上位机的双向通信。
串口接收代码
#include <STC89C52.h>
unsigned char received_data;
// 串口初始化
void UART_Init() {
SCON = 0x50; // 设置为模式1(8位UART)
TMOD = 0x20; // 设置定时器1为模式2(自动重装载)
TH1 = 0xFD; // 波特率9600,晶振11.0592MHz
TL1 = 0xFD;
TR1 = 1; // 启动定时器1
EA = 1; // 开启总中断
ES = 1; // 开启串口中断
}
// 发送单个字符
void UART_SendChar(unsigned char c) {
SBUF = c;
while (!TI); // 等待发送完成
TI = 0; // 清除发送标志
}
// 串口中断服务函数
void UART_ISR() interrupt 4 {
if (RI) { // 接收中断
received_data = SBUF; // 读取接收的数据
RI = 0; // 清除接收标志
UART_SendChar(received_data); // 回显接收到的数据
}
}
void main() {
UART_Init();
while (1) {
// 主循环可以做其他事情
}
}
代码特点:
- 使用中断方式接收数据
- 实现了数据的回显功能
- 串口初始化配置完整
使用场景:
接收上位机命令、参数配置、远程控制
定时器使用
定时器中断
使用定时器中断实现精确的时间控制。
定时器中断代码
#include <STC89C52.h>
unsigned int count = 0;
// 定时器0初始化
void Timer0_Init() {
TMOD = 0x01; // 设置定时器0为模式1(16位定时器)
TH0 = (65536 - 50000) / 256; // 定时50ms,晶振11.0592MHz
TL0 = (65536 - 50000) % 256;
EA = 1; // 开启总中断
ET0 = 1; // 开启定时器0中断
TR0 = 1; // 启动定时器0
}
// 定时器0中断服务函数
void Timer0_ISR() interrupt 1 {
TH0 = (65536 - 50000) / 256; // 重新加载初值
TL0 = (65536 - 50000) % 256;
count++;
if (count >= 20) { // 1秒(50ms * 20)
count = 0;
P1 ^= 0x01; // 翻转LED状态
}
}
void main() {
Timer0_Init();
while (1) {
// 主循环可以做其他事情
}
}
代码特点:
- 使用定时器中断实现精确计时
- 定时时间可根据需要调整
- 演示了中断服务函数的编写
使用场景:
定时任务、精确延时、频率测量
ADC转换
ADC读取
使用ADC模块读取模拟信号,实现电压测量等功能。
ADC读取代码(以STC12C5A60S2为例)
#include <STC12C5A60S2.h>
// ADC初始化
void ADC_Init() {
P1ASF = 0x01; // 设置P1.0为ADC输入通道
ADC_RES = 0; // 清除ADC结果寄存器
ADC_CONTR = 0x80; // 开启ADC电源
}
// 读取ADC值
unsigned int ADC_Read(unsigned char channel) {
ADC_CONTR = 0x80 | (channel << 3) | 0x08; // 选择通道并启动转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x10)); // 等待转换完成
ADC_CONTR &= ~0x10; // 清除转换完成标志
return (ADC_RES << 8) | ADC_RESL; // 返回10位ADC值
}
void main() {
unsigned int adc_value;
ADC_Init();
while (1) {
adc_value = ADC_Read(0); // 读取通道0的值
// 处理ADC值,比如显示或发送
}
}
代码特点:
- 实现了ADC的初始化和读取
- 支持通道选择
- 返回10位ADC值
使用场景:
电压测量、传感器信号采集、模拟量处理
PWM输出
PWM控制
使用PWM输出实现LED亮度调节、电机速度控制等功能。
PWM控制代码(以STC12C5A60S2为例)
#include <STC12C5A60S2.h>
// PWM初始化
void PWM_Init() {
P1M1 &= ~0x01; // 设置P1.0为推挽输出
P1M2 |= 0x01;
// 设置定时器1为PWM模式
TMOD &= 0x0F;
TMOD |= 0x20; // 定时器1为模式2(8位自动重装载)
TH1 = 0xFF; // PWM周期
TL1 = 0xFF;
// 设置PCA/PWM
CMOD = 0x00; // PCA时钟为系统时钟/12
CL = 0x00; // 清除PCA计数器
CH = 0x00;
// 设置PWM0
CCAPM0 = 0x42; // 开启PWM0,无中断
CCAP0L = 0x80; // PWM占空比50%
CCAP0H = 0x80;
CR = 1; // 启动PCA计数器
}
// 设置PWM占空比
void PWM_SetDuty(unsigned char duty) {
CCAP0L = duty;
CCAP0H = duty;
}
void main() {
unsigned char duty = 0;
bit direction = 1;
PWM_Init();
while (1) {
if (direction) {
duty++;
if (duty >= 0xFF) {
direction = 0;
}
} else {
duty--;
if (duty <= 0) {
direction = 1;
}
}
PWM_SetDuty(duty);
// 延时
unsigned int i, j;
for (i = 10; i > 0; i--)
for (j = 110; j > 0; j--);
}
}
代码特点:
- 实现了PWM的初始化和占空比设置
- 演示了PWM亮度渐变效果
- 适用于STC12系列芯片
使用场景:
LED亮度调节、电机速度控制、蜂鸣器音量控制
代码使用说明
如何使用这些代码
- 根据您使用的STC芯片型号,选择相应的代码示例
- 将代码复制到您的开发环境中
- 根据实际硬件连接,修改相应的引脚定义
- 编译并下载到芯片中运行
注意事项
- 不同系列的STC芯片,寄存器定义可能有所不同,请参考相应的芯片 datasheet
- 代码中的晶振频率设置可能需要根据实际使用的晶振进行调整
- 对于复杂的功能,可能需要结合多个代码示例进行实现
- 在使用中断时,注意中断优先级和嵌套问题
扩展建议
- 将常用功能封装成函数,提高代码的可重用性
- 使用结构体和枚举类型,提高代码的可读性
- 添加适当的注释,方便后期维护
- 考虑代码的健壮性,添加错误处理机制