- 打卡等级:偶尔看看III
- 打卡总天数:54
- 最近打卡:2025-05-01 09:07:55
管理员
- 积分
- 15613
|
发表于 2023-6-24 21:24:22
|
显示全部楼层
/************* 功能说明 **************
本例程基于STC32G为主控芯片的实验箱9.6进行编写测试。
使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
短接实验箱J1跳线,在J15的第1脚可测到1KHz的正弦波,在J15的第3脚可测到1KHz的方波。
P1.1脚输出PWM信号通过转换电路转成DAC,短接J14的1、2脚,通过ADC3可采集DAC电压值。
下载时, 选择默认时钟 35MHz.
******************************************/
#include "stc.h"
/************* 本地常量声明 **************/
#define MAIN_Fosc 35000000UL
/************* IO口声明 **************/
/************* 本地变量声明 **************/
/************* 本地函数声明 **************/
void Timer4_Config(void);
void PWMA_config(void);
void PWMB_config(void);
/**************** 外部函数声明和外部变量声明 *****************/
/**************** 主函数 *****************/
void main(void)
{
WTST = 0;
CKCON = 0;
EAXFR = 1; //允许访问扩展寄存器
P0M1 = 0x00; P0M0 = 0x80; //设置为准双向口,设置P0.7推挽输出
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
Timer4_Config(); //Timer4初始化, 输出1000Hz方波.
PWMA_config(); //PWM控制垂直位移
PWMB_config(); //输出1000Hz正弦波
EA = 1;
while (1)
{
}
}
//========================================================================
// 函数: void Timer4_Config(void)
// 描述: timer3初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void Timer4_Config(void)
{
T4T3M &= 0x0f; //停止计数, 定时模式, 12T模式, 不输出时钟
T4T3M |= (1<<5); //1T mode
T4H = (u8)((65536UL - MAIN_Fosc/2000) /256);
T4L = (u8)((65536UL - MAIN_Fosc/2000) %256);
T3T4PS = 0x00; //选择IO, 0x00: T3--P0.4, T3CLKO--P0.5, T4--P0.6, T4CLKO--P0.7; 0x01: T3--P0.0, T3CLKO--P0.1, T4--P0.2, T4CLKO--P0.3;
T4T3M |= (1<<4); //允许输出时钟
T4T3M |= (1<<7); //开始运行
}
//========================================================================
// 函数: void PWMA_config(void)
// 描述: PWMA初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2022-6-25
//========================================================================
void PWMA_config(void)
{
u8 ccer1;
u8 ccer2;
u8 ps;
u8 eno;
u8 PWMA_ISR_En;
P_SW2 |= 0x80; //SFR enable
PWMA_ENO = 0; // IO输出禁止
PWMA_IER = 0; // 禁止中断
PWMA_SR1 = 0; // 清除状态
PWMA_SR2 = 0; // 清除状态
ccer1 = 0;
ccer2 = 0;
ps = 0;
eno = 0;
PWMA_ISR_En = 0;
PWMA_PSCRH = 0x00; // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
PWMA_PSCRL = 0x00;
PWMA_DTR = 0; // 死区时间配置, n=0~127: DTR= n T, 0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,
// 0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T, 0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
PWMA_ARRH = 256/256; // 自动重装载寄存器, 控制PWM周期
PWMA_ARRL = 256%256;
PWMA_CCMR1 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMA_CCR1H = 128/256; // 比较值, 控制占空比(高电平时钟数)
PWMA_CCR1L = 128%256;
ccer1 |= 0x07; // 开启比较输出, 低电平有效
ps |= 0; // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
eno |= 0x02; // IO输出允许, bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P, bit3: ENO2N, bit2: ENO2P, bit1: ENO1N, bit0: ENO1P
// PWMA_ISR_En|= 0x02; // 使能中断
PWMA_CCER1 = ccer1; // 捕获/比较使能寄存器1
PWMA_CCER2 = ccer2; // 捕获/比较使能寄存器2
PWMA_PS = ps; // 选择IO
PWMA_IER = PWMA_ISR_En; //设置允许通道1~4中断处理
PWMA_BKR = 0x80; // 主输出使能 相当于总开关
PWMA_CR1 = 0x81; // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数, bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
PWMA_EGR = 0x01; //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
PWMA_ENO = eno; // 允许IO输出
}
// PWMA_PS = (0<<6)+(0<<4)+(0<<2)+0; //选择IO, 4项从高到低(从左到右)对应PWM1 PWM2 PWM3 PWM4, 0:选择P1.x, 1:选择P2.x, 2:选择P6.x,
// PWMA_PS PWM4N PWM4P PWM3N PWM3P PWM2N PWM2P PWM1N PWM1P
// 00 P1.7 P1.6 P1.5 P1.4 P1.3 P5.4 P1.1 P1.0
// 01 P2.7 P2.6 P2.5 P2.4 P2.3 P2.2 P2.1 P2.0
// 02 P6.7 P6.6 P6.5 P6.4 P6.3 P6.2 P6.1 P6.0
// 03 P3.3 P3.4 -- -- -- -- -- --
//========================================================================
// 函数: void PWMB_config(void)
// 描述: PWMA初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2022-6-25
//========================================================================
void PWMB_config(void)
{
u8 ccer1;
u8 ccer2;
u8 ps;
u8 eno;
u8 PWMB_ISR_En;
PWMB_ENO = 0; // IO输出禁止
PWMB_IER = 0; // 禁止中断
PWMB_SR1 = 0; // 清除状态
PWMB_SR2 = 0; // 清除状态
ccer1 = 0;
ccer2 = 0;
ps = 0;
eno = 0;
PWMB_ISR_En = 0;
PWMB_PSCRH = 0x00; // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
PWMB_PSCRL = 6;
PWMB_ARRH = 0; // 自动重装载寄存器, 控制PWM周期, PWM频率 = 35000000/(6+1)/250=20000
PWMB_ARRL = 250-1;
PWMB_CCMR4 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMB_CCR8H = 0; // 比较值, 控制占空比(高电平时钟数)
PWMB_CCR8L = 87;
ccer2 |= 0x50; // 开启比较输出, 高电平有效
ps |= (0<<6); // 选择IO, 0:选择P2.3, 1:选择P3.4, 2:选择P0.3, 3:选择P7.7,
eno |= 0x40; // IO输出允许, bit6: ENO8P, bit4: ENO7P, bit2: ENO6P, bit0: ENO5P
PWMB_ISR_En = 0x01; // 使能更新中断
PWMB_CCER1 = ccer1; // 捕获/比较使能寄存器1
PWMB_CCER2 = ccer2; // 捕获/比较使能寄存器2
PWMB_PS = ps; // 选择IO
PWMB_IER = PWMB_ISR_En; //设置允许通道1~4中断处理
PWMB_BKR = 0x80; // 主输出使能 相当于总开关
PWMB_CR1 = 0x81; // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数, bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
PWMB_EGR = 0x01; //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
PWMB_ENO = eno; // 允许IO输出
}
// PWMB_PS = (0<<6)+(0<<4)+(0<<2)+0; //选择IO, 4项从高到低(从左到右)对应PWM8 PWM7 PWM6 PWM5
// PWMB_PS PWM8 PWM7 PWM6 PWM5
// 00 P2.3 P2.2 P2.1 P2.0
// 01 P3.4 P3.3 P5.4 P1.7
// 02 P0.3 P0.2 P0.1 P0.0
// 03 P7.7 P7.6 P7.5 P7.4
//========================================================================
// 函数: void PWMA_ISR(void) interrupt PWMA_VECTOR
// 描述: PWMA中断处理程序. 捕获数据通过 TIM1-> CCRnH / TIM1-> CCRnL 读取
// 参数: None
// 返回: none.
// 版本: V1.0, 2021-6-1
//========================================================================
#include "SineTable.h"
u8 SineIndex;
void PWMB_ISR(void) interrupt PWMB_VECTOR
{
u8 sr1;
sr1 = PWMB_SR1; //为了快速, 中断标志用一个局部变量处理
PWMB_SR1 = 0; //清除中断标志
PWMB_SR2 = 0; //清除中断标志
if(sr1 & 0x01) //更新中断标志
{
PWMB_CCR8L = T_SIN[SineIndex]; //P1.1输出1000Hz正弦波
if(++SineIndex == 20) SineIndex = 0;
}
}
|
|