开天斧3移植AI8H系列 高级PWM输出(频率可调,脉冲计数)软件方式 C语言

移植效果 P6口闪烁显示 PWM还需调试

#include "../comm/STC8h.h" //包含此头文件后,不需要再包含"reg51.h"头文件

#include "../comm/usb.h" //USB调试及复位所需头文件

#include "intrins.h"

/****************************** 用户定义宏 ***********************************/

#define MAIN_Fosc 24000000L //定义主时钟

#define Timer0_Reload (65536UL -(MAIN_Fosc / 1000)) //Timer 0 中断频率, 1000次/秒

/*****************************************************************************/

/*************本地变量声明**************/

bit B_1ms; //1ms标志

bit PWM1_Flag;

u16 Period;

u8 Counter;

u8 msSecond;

void UpdatePwm(void);

void TxPulse(void);

//USB调试及复位所需定义

char *USER_DEVICEDESC = NULL;

char *USER_PRODUCTDESC = NULL;

char *USER_STCISPCMD = "@STCISP#"; //设置自动复位到ISP区的用户接口命令

//P3.2口按键复位所需变量

bit Key_Flag;

u16 Key_cnt;

void UpdatePwm(void);

void KeyResetScan(void);

//========================================================================

// 函数: void delay_ms(u8 ms)

// 描述: 延时函数。

// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.

// 返回: none.

// 版本: VER1.0

// 日期: 2022-6-3

// 备注:

//========================================================================

void delay_ms(u8 ms)

{

u16 i;

do{

i = MAIN_Fosc / 10000;

while(--i); //10T per loop

}while(--ms);

}

//========================================================================

// 函数: void KeyResetScan(void)

// 描述: P3.2口按键长按1秒触发软件复位,进入USB下载模式。

// 参数: none.

// 返回: none.

// 版本: VER1.0

// 日期: 2022-6-11

// 备注:

//========================================================================

void KeyResetScan(void)

{

if(!P32)

{

if(!Key_Flag)

{

Key_cnt++;

if(Key_cnt >= 1000) //连续1000ms有效按键检测

{

Key_Flag = 1; //设置按键状态,防止重复触发

USBCON = 0x00; //清除USB设置

USBCLK = 0x00;

IRC48MCR = 0x00;

delay_ms(10);

IAP_CONTR = 0x60; //触发软件复位,从ISP开始执行

while (1);

}

}

}

else

{

Key_cnt = 0;

Key_Flag = 0;

}

}

/************* 发送脉冲函数 **************/

void TxPulse(void)

{

PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道

PWMA_CCMR1 = 0x60; //设置 PWM1 模式1 输出

PWMA_CCER1 = 0x01; //使能 CC1E 通道, 高电平有效

PWMA_SR1 = 0; //清标志位

PWMA_CNTR = 0; //清计数器

PWMA_IER = 0x02; //使能捕获/比较 1 中断

}

/********************** Timer0 1ms中断函数 ************************/

void timer0(void) interrupt 1

{

B_1ms = 1;

if(PWM1_Flag)

{

Period++; //周期递增

if(Period >= 0x1000) PWM1_Flag = 0;

}

else

{

Period--; //周期递减

if(Period <= 0x0100) PWM1_Flag = 1;

}

UpdatePwm(); //设置周期、占空比

}

/******************* PWM中断函数 ********************/

void PWMA_ISR() interrupt 26

{

if(PWMA_SR1 & 0X02)

{

PWMA_SR1 &=~0X02; //清标志位

Counter++;

if(Counter >= 10) //计数10个脉冲后关闭PWM计数器

{

Counter = 0;

PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道

PWMA_CCMR1 = 0x40; //设置 PWM1 强制为无效电平

PWMA_CCER1 = 0x01; //使能 CC1E 通道, 高电平有效

PWMA_IER = 0x00; //关闭中断

}

}

}

//========================================================================

// 函数: UpdatePwm(void)

// 描述: 更新PWM周期占空比.

// 参数: none.

// 返回: none.

// 版本: V1.0, 2012-11-22

//========================================================================

void UpdatePwm(void)

{

PWMA_ARR = Period;

PWMA_CCR1 = (Period >> 1); //设置占空比时间: Period/2

}

/******************** 主函数 **************************/

void main(void)

{

P_SW2 |= 0x80; //扩展寄存器(XFR)访问使能

RSTFLAG |= 0x04; //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口

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; //设置为准双向口

//USB调试及复位所需代码-----

P3M0 &= ~0x03;

P3M1 |= 0x03;

IRC48MCR = 0x80;

while (!(IRC48MCR & 0x01));

usb_init();

//-------------------------

// Timer0初始化

TMOD &= 0xf0;//16 bits timer auto-reload

AUXR |= 0x80;//Timer0 set as 1T

TH0 = (u8)(Timer0_Reload / 256);

TL0 = (u8)(Timer0_Reload % 256);

ET0 = 1; //Timer0 interrupt enable

TR0 = 1; //Tiner0 run

IE2 |= 0x80; //IE2相关的中断位操作使能后,需要重新设置EUSB

EA = 1; //打开总中断

P6=0X00;

delay_ms(50);

P6=0XFF;

delay_ms(50);

P6=0X00;

delay_ms(50);

P6=0XFF;

P6=0X00;

delay_ms(50);

P6=0XFF;

delay_ms(50);

P6=0X00;

delay_ms(50);

P6=0XFF;

P6=0X00;

delay_ms(50);

P6=0XFF;

delay_ms(50);

P6=0X00;

delay_ms(50);

P6=0XFF;

while (1)

{

if (bUsbOutReady) //USB调试及复位所需代码

{

// memcpy(UsbInBuffer, UsbOutBuffer, 64); //原路返回, 用于测试HID

// usb_IN();

usb_OUT_done();

}

}

}

原始例程文件

//测试工作频率为24MHz

/************* 功能说明 **************

本例程基于STC8H8K64U为主控芯片的实验箱8进行编写测试,

STC8H系列芯片可通用参考.

高级PWM定时器实现高速PWM脉冲输出.

周期/占空比可调, 通过比较/捕获中断进行脉冲个数计数.

通过P6口演示输出,每隔10ms输出一次PWM,计数10个脉冲后停止输出.

定时器每1ms调整PWM周期.

下载时,选择时钟24MHZ (用户可自行修改频率).

******************************************/

#include "reg51.h"

#include "intrins.h"

#define MAIN_Fosc 24000000L

typedef unsigned char u8;

typedef unsigned int u16;

typedef unsigned long u32;

sfr TH2 = 0xD6;

sfr TL2 = 0xD7;

sfr IE2 = 0xAF;

sfr INT_CLKO = 0x8F;

sfr AUXR = 0x8E;

sfr P_SW1 = 0xA2;

sfr P_SW2 = 0xBA;

sfr P4 = 0xC0;

sfr P5 = 0xC8;

sfr P6 = 0xE8;

sfr P7 = 0xF8;

sfr P1M1 = 0x91;

sfr P1M0 = 0x92;

sfr P0M1 = 0x93;

sfr P0M0 = 0x94;

sfr P2M1 = 0x95;

sfr P2M0 = 0x96;

sfr P3M1 = 0xB1;

sfr P3M0 = 0xB2;

sfr P4M1 = 0xB3;

sfr P4M0 = 0xB4;

sfr P5M1 = 0xC9;

sfr P5M0 = 0xCA;

sfr P6M1 = 0xCB;

sfr P6M0 = 0xCC;

sfr P7M1 = 0xE1;

sfr P7M0 = 0xE2;

sbit P00 = P0^0;

sbit P01 = P0^1;

sbit P02 = P0^2;

sbit P03 = P0^3;

sbit P04 = P0^4;

sbit P05 = P0^5;

sbit P06 = P0^6;

sbit P07 = P0^7;

sbit P10 = P1^0;

sbit P11 = P1^1;

sbit P12 = P1^2;

sbit P13 = P1^3;

sbit P14 = P1^4;

sbit P15 = P1^5;

sbit P16 = P1^6;

sbit P17 = P1^7;

sbit P20 = P2^0;

sbit P21 = P2^1;

sbit P22 = P2^2;

sbit P23 = P2^3;

sbit P24 = P2^4;

sbit P25 = P2^5;

sbit P26 = P2^6;

sbit P27 = P2^7;

sbit P30 = P3^0;

sbit P31 = P3^1;

sbit P32 = P3^2;

sbit P33 = P3^3;

sbit P34 = P3^4;

sbit P35 = P3^5;

sbit P36 = P3^6;

sbit P37 = P3^7;

sbit P40 = P4^0;

sbit P41 = P4^1;

sbit P42 = P4^2;

sbit P43 = P4^3;

sbit P44 = P4^4;

sbit P45 = P4^5;

sbit P46 = P4^6;

sbit P47 = P4^7;

sbit P50 = P5^0;

sbit P51 = P5^1;

sbit P52 = P5^2;

sbit P53 = P5^3;

sbit P54 = P5^4;

sbit P55 = P5^5;

sbit P56 = P5^6;

sbit P57 = P5^7;

/******************************用户定义宏 ***********************************/

#define Timer0_Reload (65536UL -(MAIN_Fosc / 1000))

#define PWMA_ENO (*(unsigned char volatile xdata *) 0xFEB1)

#define PWMA_PS (*(unsigned char volatile xdata *) 0xFEB2)

#define PWMB_ENO (*(unsigned char volatile xdata *) 0xFEB5)

#define PWMB_PS (*(unsigned char volatile xdata *) 0xFEB6)

#define PWMA_CR1 (*(unsigned char volatile xdata *) 0xFEC0)

#define PWMA_CR2 (*(unsigned char volatile xdata *) 0xFEC1)

#define PWMA_SMCR (*(unsigned char volatile xdata *) 0xFEC2)

#define PWMA_ETR (*(unsigned char volatile xdata *) 0xFEC3)

#define PWMA_IER (*(unsigned char volatile xdata *) 0xFEC4)

#define PWMA_SR1 (*(unsigned char volatile xdata *) 0xFEC5)

#define PWMA_SR2 (*(unsigned char volatile xdata *) 0xFEC6)

#define PWMA_EGR (*(unsigned char volatile xdata *) 0xFEC7)

#define PWMA_CCMR1 (*(unsigned char volatile xdata *) 0xFEC8)

#define PWMA_CCMR2 (*(unsigned char volatile xdata *) 0xFEC9)

#define PWMA_CCMR3 (*(unsigned char volatile xdata *) 0xFECA)

#define PWMA_CCMR4 (*(unsigned char volatile xdata *) 0xFECB)

#define PWMA_CCER1 (*(unsigned char volatile xdata *) 0xFECC)

#define PWMA_CCER2 (*(unsigned char volatile xdata *) 0xFECD)

#define PWMA_CNTR (*(unsigned int volatile xdata *) 0xFECE)

#define PWMA_CNTRH (*(unsigned char volatile xdata *) 0xFECE)

#define PWMA_CNTRL (*(unsigned char volatile xdata *) 0xFECF)

#define PWMA_PSCRH (*(unsigned char volatile xdata *) 0xFED0)

#define PWMA_PSCRL (*(unsigned char volatile xdata *) 0xFED1)

#define PWMA_ARR (*(unsigned int volatile xdata *) 0xFED2)

#define PWMA_ARRH (*(unsigned char volatile xdata *) 0xFED2)

#define PWMA_ARRL (*(unsigned char volatile xdata *) 0xFED3)

#define PWMA_RCR (*(unsigned char volatile xdata *) 0xFED4)

#define PWMA_CCR1 (*(unsigned int volatile xdata *) 0xFED5)

#define PWMA_CCR1H (*(unsigned char volatile xdata *) 0xFED5)

#define PWMA_CCR1L (*(unsigned char volatile xdata *) 0xFED6)

#define PWMA_CCR2 (*(unsigned int volatile xdata *) 0xFED7)

#define PWMA_CCR2H (*(unsigned char volatile xdata *) 0xFED7)

#define PWMA_CCR2L (*(unsigned char volatile xdata *) 0xFED8)

#define PWMA_CCR3 (*(unsigned int volatile xdata *) 0xFED9)

#define PWMA_CCR3H (*(unsigned char volatile xdata *) 0xFED9)

#define PWMA_CCR3L (*(unsigned char volatile xdata *) 0xFEDA)

#define PWMA_CCR4 (*(unsigned int volatile xdata *) 0xFEDB)

#define PWMA_CCR4H (*(unsigned char volatile xdata *) 0xFEDB)

#define PWMA_CCR4L (*(unsigned char volatile xdata *) 0xFEDC)

#define PWMA_BKR (*(unsigned char volatile xdata *) 0xFEDD)

#define PWMA_DTR (*(unsigned char volatile xdata *) 0xFEDE)

#define PWMA_OISR (*(unsigned char volatile xdata *) 0xFEDF)

/*****************************************************************************/

#define PWM1_1 0x00 //P:P1.0 N:P1.1

#define PWM1_2 0x01 //P:P2.0 N:P2.1

#define PWM1_3 0x02 //P:P6.0 N:P6.1

#define PWM2_1 0x00 //P:P1.2/P5.4 N:P1.3

#define PWM2_2 0x04 //P:P2.2 N:P2.3

#define PWM2_3 0x08 //P:P6.2 N:P6.3

#define PWM3_1 0x00 //P:P1.4 N:P1.5

#define PWM3_2 0x10 //P:P2.4 N:P2.5

#define PWM3_3 0x20 //P:P6.4 N:P6.5

#define PWM4_1 0x00 //P:P1.6 N:P1.7

#define PWM4_2 0x40 //P:P2.6 N:P2.7

#define PWM4_3 0x80 //P:P6.6 N:P6.7

#define PWM4_4 0xC0 //P:P3.4 N:P3.3

#define ENO1P 0x01

#define ENO1N 0x02

#define ENO2P 0x04

#define ENO2N 0x08

#define ENO3P 0x10

#define ENO3N 0x20

#define ENO4P 0x40

#define ENO4N 0x80

/*************本地变量声明**************/

bit B_1ms; //1ms标志

bit PWM1_Flag;

u16 Period;

u8 Counter;

u8 msSecond;

void UpdatePwm(void);

void TxPulse(void);

/******************** 主函数 **************************/

void main(void)

{

P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口

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; //设置为准双向口

PWM1_Flag = 0;

Counter = 0;

Period = 0x1000;

//Timer0初始化

AUXR = 0x80; //Timer0 set as 1T,16 bits timer auto-reload,

TH0 = (u8)(Timer0_Reload / 256);

TL0 = (u8)(Timer0_Reload % 256);

ET0 = 1; //Timer0 interrupt enable

TR0 = 1; //Tiner0 run

P_SW2 |= 0x80; //使能XFR访问

PWMA_ENO = 0x00;

PWMA_ENO |= ENO1P; //使能输出

PWMA_PS = 0x00; //高级 PWM 通道输出脚选择位

PWMA_PS |= PWM1_3; //选择 PWM1_3 通道

UpdatePwm();

PWMA_BKR = 0x80; //使能主输出

PWMA_CR1 |= 0x01; //开始计时

P40 = 0; //给LED供电

EA = 1; //打开总中断

while (1)

{

if(B_1ms)

{

B_1ms = 0;

msSecond++;

if(msSecond >= 10)

{

msSecond = 0;

TxPulse(); //10ms启动一次PWM输出

}

}

}

}

/************* 发送脉冲函数 **************/

void TxPulse(void)

{

PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道

PWMA_CCMR1 = 0x60; //设置 PWM1 模式1 输出

PWMA_CCER1 = 0x01; //使能 CC1E 通道, 高电平有效

PWMA_SR1 = 0; //清标志位

PWMA_CNTR = 0; //清计数器

PWMA_IER = 0x02; //使能捕获/比较 1 中断

}

/********************** Timer0 1ms中断函数 ************************/

void timer0(void) interrupt 1

{

B_1ms = 1;

if(PWM1_Flag)

{

Period++; //周期递增

if(Period >= 0x1000) PWM1_Flag = 0;

}

else

{

Period--; //周期递减

if(Period <= 0x0100) PWM1_Flag = 1;

}

UpdatePwm(); //设置周期、占空比

}

/******************* PWM中断函数 ********************/

void PWMA_ISR() interrupt 26

{

if(PWMA_SR1 & 0X02)

{

PWMA_SR1 &=~0X02; //清标志位

Counter++;

if(Counter >= 10) //计数10个脉冲后关闭PWM计数器

{

Counter = 0;

PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道

PWMA_CCMR1 = 0x40; //设置 PWM1 强制为无效电平

PWMA_CCER1 = 0x01; //使能 CC1E 通道, 高电平有效

PWMA_IER = 0x00; //关闭中断

}

}

}

//========================================================================

// 函数: UpdatePwm(void)

// 描述: 更新PWM周期占空比.

// 参数: none.

// 返回: none.

// 版本: V1.0, 2012-11-22

//========================================================================

void UpdatePwm(void)

{

PWMA_ARR = Period;

PWMA_CCR1 = (Period >> 1); //设置占空比时间: Period/2

}

相关推荐
如愿小李3 小时前
STM32之L298N电机驱动模块
stm32·单片机·嵌入式硬件
CC呢5 小时前
基于单片机宠物喂食器/智能宠物窝/智能饲养
单片机·嵌入式硬件·物联网·宠物喂食
DIY机器人工房6 小时前
关于在VScode中使用git的一些步骤常用命令及其常见问题:
大数据·stm32·单片机·嵌入式硬件·elasticsearch·搜索引擎·diy机器人工房
muub6 小时前
【黄山派-SF32LB52】—硬件原理图学习笔记
单片机·嵌入式硬件·原理图·黄山派·sf32·思澈科技·立创开发板
QL.ql11 小时前
HAL库的串口
单片机·嵌入式硬件
soulermax20 小时前
数字ic后端设计从入门到精通11(含fusion compiler, tcl教学)全定制设计入门
嵌入式硬件·fpga开发·硬件架构
会编程的小孩21 小时前
stm32驱动双步进电机
stm32·单片机·嵌入式硬件
weixin_1122331 天前
基于STM32单片机车牌识别系统摄像头图像处理设计的论文
图像处理·stm32·单片机
国科安芯1 天前
抗辐照与国产替代:ASM1042在卫星光纤放大器(EDFA)中的应用探索
网络·单片机·嵌入式硬件·安全·硬件架构