|
|
楼主 |
发表于 2026-10-10 10:44:26
|
显示全部楼层
芯片丝印:STC8H2K17U 45I TSSOP20 2417A536774.HA(或为BA,看不太清)
读DID寄存器给出的芯片版本:B
STC-ISP检测选项:
-----------------------------------------------------------------
正在检测目标单片机 ...
单片机型号: STC8H2K17U
软件协议, V3.0: 7.4.7U
当前芯片的硬件选项为:
. 当前系统ISP工作频率: 23.959MHz
. 上次下载设置的下次用户程序运行使用的内部IRC振荡器的频率: 35.940MHz
. 掉电唤醒定时器的频率: 35.075KHz
. 振荡器放大增益使能
. 用户EEPROM大小被设置为 0.5 K
. P3.2和P3.3与下次下载无关
. 上电复位时增加额外的复位延时
. 复位引脚用作普通I/O口
. P5.4口不切换为P1.2
. 不交换P1.0口和P1.1位置
. 检测到低压时复位
. 低压检测门槛电压 : 2.00 V
. 上电复位时,硬件不启动内部看门狗
. 上电自动启动内部看门狗时的预分频数为 : 256
. 空闲状态时看门狗定时器停止计数
. 下次下载用户程序时,将用户EEPROM区一并擦除
. 下次下载用户程序时,没有相关的端口控制485
. 下次下载时不需要校验下载口令
. 未使能芯片的仿真功能
. 内部参考电压: 1190 mV (参考范围: 1100~1300mV)
单片机型号: STC8H2K17U
软件协议, V3.0: 7.4.7U
操作成功 !(2026-10-10 10:36:54)
-----------------------------------------------------------------
完整代码:(第191行HSCLKDIV从1切换至2后可以正常触发ADC)
#include "STC8H.H"
#include <string.h>
#include <stdio.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int i16;
typedef signed long i32;
enum {
GPIO_MODE_IN_OUT = 0,
GPIO_MODE_OUT_PP = 1,
GPIO_MODE_AIN = 2,
GPIO_MODE_OUT_OD = 3
};
static void gpio_mode_set(u8 port, u8 pin, u8 mode);
#define FOSC 36000000UL
#define UART1_BAUDRATE 115200
sfr DID = 0xa7;
static u8 get_chip_version() {
u8 _;
IAP_ADDRL = 0x02;
_ = DID;
return _;
}
static void clock_init() {
int i;
CLKSEL = 0x80; // 144mhz pwm
CLKDIV = 0;
PLLCR = 0xc0;
// wait until pll ready
for(i=0; i<1000; i++) _nop_();
CLKSEL |= 0x40; // hs clk source
}
volatile bit uart1_busy = 0;
static void uart_init() {
// uart1 using tim1 as clocksource
const u8 baudrate_reg = (256 - (FOSC / UART1_BAUDRATE + 16) / 32);
gpio_mode_set(3, 0, GPIO_MODE_IN_OUT);
gpio_mode_set(3, 1, GPIO_MODE_IN_OUT);
SCON = 0x40; // tx only, 8bit
TMOD = 0x20; // 8bit timer, auto reload TH to TL
TL1 = baudrate_reg;
TH1 = baudrate_reg;
TR1 = 1;
AUXR = 0x40;
ES = 1; // enable uart interrupt
}
static void gpio_default_init() {
// set all pins to analog input
P0M0 = 0x00; P0M1 = 0xff;
P1M0 = 0x00; P1M1 = 0xff;
P2M0 = 0x00; P2M1 = 0xff;
P3M0 = 0x00; P3M1 = 0xff;
P4M0 = 0x00; P4M1 = 0xff;
P5M0 = 0x00; P5M1 = 0xff;
P6M0 = 0x00; P6M1 = 0xff;
P7M0 = 0x00; P7M1 = 0xff;
}
volatile bit tim11_finished = 0;
static void delay_init() {
T11CR = 0x00; // freq=sysclk/12
T11PS = 0; // prescaler
}
void udelay(u32 usec) {
u32 ticks = usec * ((FOSC / 1000000UL) / 12UL);
while(ticks) {
u16 _ = ticks > 0xffff ? 0xffff : ticks;
ticks -= _;
_ = 65535 - _;
T11L = _;
T11H = _ >> 8;
T11CR |= 0x82;
while(!tim11_finished);
tim11_finished = 0;
}
}
void mdelay(u32 msec) {
udelay(msec * 1000);
}
static u8 hspwma_read_async(u8 addr) {
u8 _;
while(HSPWMA_ADR & 0x80);
HSPWMA_ADR = addr | 0x80;
while(HSPWMA_ADR & 0x80);
_ = HSPWMA_DAT;
return _;
}
static void hspwma_write_async(u8 addr, u8 val) {
while(HSPWMA_ADR & 0x80);
HSPWMA_DAT = val;
HSPWMA_ADR = addr & 0x7f;
}
static u8 hspwmb_read_async(u8 addr) {
u8 _;
while(HSPWMB_ADR & 0x80);
HSPWMB_ADR = addr | 0x80;
while(HSPWMB_ADR & 0x80);
_ = HSPWMB_DAT;
return _;
}
static void hspwmb_write_async(u8 addr, u8 val) {
while(HSPWMB_ADR & 0x80);
HSPWMB_DAT = val;
HSPWMB_ADR = addr & 0x7f;
}
static void adc_start() {
ADC_CONTR |= 0x40;
_nop_();
_nop_();
}
static void adc_wait() {
while(!(ADC_CONTR & 0x20));
}
static u16 adc_get() {
u16 _;
ADC_CONTR &= ~0x20;
_ = (ADC_RES << 8) | ADC_RESL;
return _;
}
static void adc_select_channel(u8 ch) {
u8 _ = ADC_CONTR;
_ &= 0xf0;
_ |= ch & 0x0f;
ADC_CONTR = _;
}
#define VREFINT_MV 1190UL
u16 vrefint_raw = 0;
u16 vdd_mv = 0;
static void adc_init() {
u32 _;
const int N = 32;
int i;
// basic configuration
ADCTIM = 0x32; // sample time: 3 cycles
ADC_CONTR |= 0x80; // power on
ADCCFG = 0x20; // left align, speed=sysclk/2/1 (fastest)
mdelay(10);
// vrefint raw averaging and vdd computing
adc_select_channel(15);
_ = 0;
for(i=0; i<=N; i++) {
u16 raw;
adc_start();
adc_wait();
raw = adc_get();
if(i != 0) {
_ += raw;
}
}
vrefint_raw = _ / N;
vdd_mv = VREFINT_MV * 4096 / vrefint_raw;
// configure to adc sample pin
gpio_mode_set(1, 4, GPIO_MODE_AIN);
adc_select_channel(4);
ADC_CONTR |= 0x10; // enable pwm trigger
EADC = 1;
}
#define PWM_PERIOD (1000 - 1)
static void pwm_and_dac_init() {
const u16 rep_cnt = 10 - 1;
u8 _;
// dac using hspwmb.ch8
gpio_mode_set(3, 4, GPIO_MODE_OUT_PP);
HSCLKDIV = 1;
HSPWMB_CFG = 0x03;
hspwmb_write_async((u8)&PWMB_CCER2, 0x00);
hspwmb_write_async((u8)&PWMB_CCMR4, 0x00);
PWMB_PS = 0x40; // select p3.4 as ch8 output
hspwmb_write_async((u8)&PWMB_CCER2, 0x10);
hspwmb_write_async((u8)&PWMB_CCMR4, 0x64);
hspwmb_write_async((u8)&PWMB_ENO, 0x40);
hspwmb_write_async((u8)&PWMB_BKR, 0x80);
hspwmb_write_async((u8)&PWMB_CCR8H, 0); // h before l
hspwmb_write_async((u8)&PWMB_CCR8L, 0);
hspwmb_write_async((u8)&PWMB_ARRH, (PWM_PERIOD >> 8) & 0xff);
hspwmb_write_async((u8)&PWMB_ARRL, PWM_PERIOD & 0xff);
// mosfet
gpio_mode_set(3, 3, GPIO_MODE_OUT_PP);
hspwmb_write_async((u8)&PWMB_CCMR3, 0x00);
PWMB_PS |= 0x10; // select p3.3
_ = hspwmb_read_async((u8)&PWMB_CCER2);
_ &= 0x0f; _ |= 0x01;
hspwmb_write_async((u8)&PWMB_CCER2, _);
hspwmb_write_async((u8)&PWMB_CCMR3, 0x64);
_ = hspwmb_read_async((u8)&PWMB_ENO);
_ |= 0x10;
hspwmb_write_async((u8)&PWMB_ENO, _);
hspwmb_write_async((u8)&PWMB_CCR7H, 0);
hspwmb_write_async((u8)&PWMB_CCR7L, 50);
//// hspwma in internal clock mode
//HSPWMA_CFG = 0x03;
//hspwma_write_async((u8)&PWMA_CR2, 0x24); // pwma uev as trgo, triggering adc to start
//hspwma_write_async((u8)&PWMA_ENO, 0x00); // no real output to pin
//hspwma_write_async((u8)&PWMA_BKR, 0x00); // master output disabled
//hspwma_write_async((u8)&PWMA_ARRH, (rep_cnt >> 8) & 0xff);
//hspwma_write_async((u8)&PWMA_ARRL, rep_cnt & 0xff);
//hspwma_write_async((u8)&PWMA_CR1, 0x01); // enable pwma
// hspwma in slave mode: pwmb as master, pwma as slave
HSPWMA_CFG = 0x03;
hspwmb_write_async((u8)&PWMB_CR2, 0x64);
hspwma_write_async((u8)&PWMA_SMCR, 0xa7); // pwma in slave mode, external clock mode 1
hspwma_write_async((u8)&PWMA_CR2, 0x20);
hspwma_write_async((u8)&PWMA_ENO, 0x00); // no real output to pin
hspwma_write_async((u8)&PWMA_BKR, 0x00); // master output disabled
hspwma_write_async((u8)&PWMA_ARRH, (rep_cnt >> 8) & 0xff);
hspwma_write_async((u8)&PWMA_ARRL, rep_cnt & 0xff);
hspwma_write_async((u8)&PWMA_SR1, 0x00);
hspwma_write_async((u8)&PWMA_CR1, 0x01); // enable pwma
// final
hspwmb_write_async((u8)&PWMB_CR1, 0x01); // enable pwmb
}
static void init() {
P_SW2 |= 0x80; // enable access to xfr
IAP_TPS = FOSC / 1000000UL;
clock_init();
EA = 1;
gpio_default_init();
uart_init();
delay_init();
adc_init();
pwm_and_dac_init();
}
volatile u32 adc_cnt = 0;
void main() {
u16 _;
u8 chip_version;
init();
chip_version = get_chip_version();
printf("chip version %c\n", 'A'+chip_version);
while(1) {
printf("adc_cnt=%lu\n", adc_cnt);
adc_cnt = 0;
_ = hspwma_read_async((u8)&PWMA_CNTRH);
_ <<= 8;
_ |= hspwma_read_async((u8)&PWMA_CNTRL);
printf("HSPWMA.CNTR=%u\n", _);
//u16 _ = hspwmb_read_async((u8)&PWMB_CNTRH);
//_ <<= 8;
//_ |= hspwmb_read_async((u8)&PWMB_CNTRL);
//printf("HSPWMB.CNTR=0x%x\n", _);
//adc_start();
mdelay(1000);
}
}
char putchar(char ch) {
while(uart1_busy);
uart1_busy = 1;
SBUF = ch;
return ch;
}
static void gpio_mode_set(u8 port, u8 pin, u8 mode) {
u8 pxm0, pxm1;
switch(port) {
case 0: {
pxm0 = P0M0; pxm1 = P0M1;
} break;
case 1: {
pxm0 = P1M0; pxm1 = P1M1;
} break;
case 2: {
pxm0 = P2M0; pxm1 = P2M1;
} break;
case 3: {
pxm0 = P3M0; pxm1 = P3M1;
} break;
case 4: {
pxm0 = P4M0; pxm1 = P4M1;
} break;
case 5: {
pxm0 = P5M0; pxm1 = P5M1;
} break;
case 6: {
pxm0 = P6M0; pxm1 = P6M1;
} break;
case 7: {
pxm0 = P7M0; pxm1 = P7M1;
} break;
}
if(mode & 1) {
pxm0 |= 1<<pin;
} else {
pxm0 &= ~(1<<pin);
}
if(mode & 2) {
pxm1 |= 1<<pin;
} else {
pxm1 &= ~(1<<pin);
}
switch(port) {
case 0: {
P0M0 = pxm0; P0M1 = pxm1;
} break;
case 1: {
P1M0 = pxm0; P1M1 = pxm1;
} break;
case 2: {
P2M0 = pxm0; P2M1 = pxm1;
} break;
case 3: {
P3M0 = pxm0; P3M1 = pxm1;
} break;
case 4: {
P4M0 = pxm0; P4M1 = pxm1;
} break;
case 5: {
P5M0 = pxm0; P5M1 = pxm1;
} break;
case 6: {
P6M0 = pxm0; P6M1 = pxm1;
} break;
case 7: {
P7M0 = pxm0; P7M1 = pxm1;
} break;
}
}
void UART1_IRQHandler() interrupt 4 {
if(TI) {
TI = 0;
uart1_busy = 0;
}
}
void ADC_IRQHandler() interrupt 5 {
ADC_CONTR &= ~0x20;
adc_cnt++;
}
void TIM11_IRQHandler() interrupt 13 {
T11CR &= ~0x01;
tim11_finished = 1;
}
|
|