关于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

五、外部中断
参考 STC8G1K08A外部中断的使用(原理+代码+完整工程)_stc8g1k08中断-CSDN博客

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐