STC8G1K08A 配置使用
STC8G1K08A的串口配置、ADC使用
关于STC8G1K08A的个人学习记录,随手记录的,请大佬指教
本人编译时发现 VS code 星辰51 插件挺好用的,还有STC-ISP 烧录软件本身也提供了许多帮助

烧录时接线可参考下图(找不到下图来源了)
SYSclk :是单片机的系统时钟频率,通常由外部晶振或内部时钟源提供,是单片机工作的基础时钟频率。本文使用IRC(内部振荡器),不同时钟频率有不同优点
如11.0592 MHz频率,标准的晶振频率,特别适合用于串行通信(UART)
#include "config.h"
#include "STC8G_PCA.h"
unsigned int Set_ADC_level(float level){
return (unsigned int)(10/(level +10) * 1023);
}
void main(){
unsigned int prev_vol = 0; // 用于存储前次电压值
unsigned int current_vol = 0; // 用于存储当前电压值
// 初始化所有IO口为准双向模式
P0M0=0x00;P0M1=0x00;
P1M0=0x00;P1M1=0x00;
P2M0=0x00;P2M1=0x00;
P3M0=0x06;P3M1=0x08; // 设置P3.3为高阻输入,P3.2和P3.1为推挽输出
P4M0=0x00;P4M1=0x00;
P5M0=0x30;P5M1=0x00; // 设置P5.4和P5.5为推挽输出
P_SW2 |= 0x80; // 允许访问扩展寄存器
ADCTIM = 0x3F; // 设置ADC采样时间=31时钟,保持时间=1时钟
P_SW2 &= 0x7F;
ADCCFG = 0x2F; // 设置ADC时钟为系统时钟/2/16,结果右对齐
ADC_CONTR = 0x83; // 使能ADC+选择通道3(P3.3)
_nop_();
while(1){
ADC_CONTR |= 0x40; // 启动AD转换
_nop_();
while(!(ADC_CONTR & 0x20)); // 等待转换完成
ADC_CONTR &= ~0x20; // 清除标志位
// 读取10位ADC结果(右对齐)
current_vol = (ADC_RES << 8) | ADC_RESL;
// 根据ADC结果控制
if (current_vol >= 807) // Set_Adc_Lever(2.6727)
{
//功能逻辑补充
}
// 0x200对应的电压约为1.65V, 1024* v/Vref 再转化为16进制 (Vref 就是 VCC, 3.3V)
else {
//功能逻辑补充
}
// 电压上升检测(带滞回防抖动)简单测试
// if(current_vol > prev_vol && (current_vol - prev_vol) > 10) {
// P54 = 0; // 电压上升时点亮LED
// P55 = 1;
// } else {
// P54 = 1; // 电压下降时熄灭LED
// P55 = 0;
// }
// prev_vol = current_vol; // 更新前次电压值
}
}
/* 通道轮询
#define ADC_CH_NUM 2
const uint8_t ch_list[ADC_CH_NUM] = {0x00, 0x03}; // 通道列表
for(uint8_t i=0; i<ADC_CH_NUM; i++){
ADC_CONTR = 0x80 | ch_list[i];
// ...启动转换和读取操作...
}
*/
一、串口配置
PnM1.x PnM0.x 决定模式:
0 0:准双向模式
0 1:推挽输出
1 0:高阻输入(仅输入)
1 1:开漏输出
例如 P3M1 = 0000 0101 P3M0 = 0000 0110
即 p3.0 是10 即高阻输入,p3.1是01 推挽输出 等
二、模数转换模块ADC的配置
ADC_CONTR
0x83 = 1000 0011 ,1000中1是电源是否开启,0011是选择通道3
ADCCFG = 0x2F
0x2F = 0010 1111, ADCCFG由右往左分别是 b0-b7,b0-b4设置 ADC 工作时钟频率SPEED
Fadc= SYSclk / (2×(SPEED+1))
B5是转换格式控制位,1代表右对齐,0代表左对齐,需查手册确认
右对齐 (ADC_SetResultAlignmentRight()):
低有效位存储在ADC_RESL,高有效位存储在ADC_RES的低几位。
数据提取和组合较为简单,适合大多数应用场景。适用于直接使用ADC结果进行阈值判断和控制。
左对齐 (ADC_SetResultAlignmentLeft()):
高有效位存储在ADC_RESL,低有效位存储在ADC_RES。
数据提取和组合较为复杂,需要额外的位操作。适用于需要优先处理高有效位的特定场合。
三、定时器
//定时器0初始化
void Timer0_Init(void) //10毫秒@24.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式: 模式0,16位自动重装载
TL0 = 0xE0; //设置定时初始值
TH0 = 0xB1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
PT0 = 0; //定时器0优先级置低,可选择
}
// 定时器0中断服务程序
void Timer0_Isr(void) interrupt 1
{
P55 = ~P55; // 翻转P5.5输出
}

参考自 STC8G1K08A定时器的使用(原理+代码+完整工程)-CSDN博客
四、输出PWM波
需先配置串口推挽输出,确认哪个串口对应pwm输出口
void PWM_Init(void)
{
CCON = 0x00;
CMOD = 0x08; //PCA时钟为系统时钟
CL = 0x00; //PCA计数器初始值低8位
CH = 0x00; //PCA计数器初始值高8位
CCAPM0 = 0x42; //PCA模块0为PWM工作模式
PCA_PWM0 = 0x80; //PCA模块1输出6位PWM
CCAP0L = 0x00; //PWM占空比为50% 8000 / ffff
CCAP0H = 0x80;
PCA_PWM1 &= 0xC0;
CCAP1H = 0x00; //PWM1 固定输出高电平
PCA_PWM2 &= 0x3F;
CCAP1H = 0xFF; //PWM2 固定输出低电平
CR = 1; //启动PCA计时器
}
CH与CL共同组成计数器初始值,CCAP0H与CCAP0L组成影响占空比,必须先写低位L再写高位H


更多推荐



所有评论(0)