//====================================================================
//=========================舵机测试仪==================================
//=================MCU: HC89S003F4 2020-2-26==========================
//========================编程:荆棘鸟=================================
//=====================================================================
#define ALLOCATE_EXTERN
#include "HC89S003F4.h"
#define Uint unsigned int
#define Uchar unsigned char
//======================LED数码管GPIO设置==============================
sbit SMG_COM1 = P1^0; // ==========
sbit SMG_COM2 = P2^1; // || ||
sbit SMG_COM3 = P0^6; // || ||
sbit SMG_COM4 = P0^4; // || ||
sbit SMG_A = P2^7; // || ||
sbit SMG_B = P0^7; // ==========
sbit SMG_C = P0^2; // || ||
sbit SMG_D = P0^0; // || ||
sbit SMG_E = P1^1; // || ||
sbit SMG_F = P2^2; // || ||
sbit SMG_G = P0^3; // ==========
//sbit SMG_DP = P0^1;
unsigned int gui_AdcValue = 0; //用于存放ADC的值
unsigned int gui_AdcValue1 = 0; //用于存放数显的值
unsigned int gui_AdcValue2 = 0; //用于存放占空比的值
/*****************************************************************************************/
// * @说明 延时函数
// * @参数 fui_i : 延时时间
// * @返回值 无
// * @注 Fcpu = 16MHz,fui_i = 1时,延时时间约为2us
/****************************************************************************************/
void Delay_2us(unsigned int fui_i)
{
while(fui_i--);
}
void Delay_ms(unsigned int i)
{
unsigned int x,y;
for(x=i;x>0;x--)
for(y=610;y>0;y--);
}
/************************************系统初始化****************************************/
void SystemInit()
{
WDTCCR = 0x00; //关闭看门狗
//本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
CLKSWR = 0x51; //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
CLKDIV = 0x01; //Fosc 1分频得到Fcpu,Fcpu=16MHz
/************************************ADC初始化*****************************************/
P0M2 = P0M2&0x0F|0x03; //P05设置为模拟输入
ADCC0 = 0x80; //打开ADC转换电源
Delay_2us(10); //延时20us,确保ADC系统稳定
ADCC1 = 0x05; //选择外部通道1
ADCC2 = 0x4D; //转换结果12位数据,数据右对齐,ADC时钟16分频
PWM0_MAP = 0x01; //PWM0通道映射P01口
PWM0C = 0x03; //PWM0高有效,PWM01高有效,时钟8分频
//独立模式下,PWM0和PWM01共用一个周期寄存器
//PWM0的占空比调节使用 PWM0组的占空比寄存器
//PWM01的占空比调节使用 PWM0组的死区寄存器
//周期计算 = 0x9C4O / (Fosc / PWM分频系数) (Fosc见系统时钟配置的部分)
// = 0x9C40 / (16000000 / 8)
// = 40000 /2000000
// = 200000 50Hz
PWM0PH = 0x9C; //周期高4位设置为0x9C
PWM0PL = 0x40; //周期低8位设置为0x40
PWM0EN = 0x0F; //使能PWM0,工作于独立模式
}
/*********************************设置IO口模式*****************************************/
void GpioInit()
{
/***************************************************************************************
* @实现效果 设置各个IO口的工作状态
***************************************************************************************/
/***********************************设置IO口模式***************************************/
//P0M1 = P0M1&0xF0|0x00; //P02设置为输入(非施密特)
//P0M0 = P0M0&0x0F|0x10; //P01设置为带下拉输入(非施密特)
//P0M0 = P0M0&0xF0|0x02; //P00设置为带上拉输入(非施密特)
//P1M0 = P1M0&0x0F|0x30; //P11设置为带模拟输入
//P2M0 = P2M0&0xF0|0x04; //P20设置为输入(施密特)
//P0M2 = P0M2&0x0F|0x50; //P05设置为带下拉输入(施密特)
//P0M2 = P0M2&0xF0|0x06; //P04设置为带上拉输入(施密特)
//P0M3 = P0M3&0x0F|0x80; //P07设置为推挽输出
//P0M3 = P0M3&0xF0|0x09; //P06设置为开漏输出
//P2M1 = P2M1&0xF0|0x0A; //P22设置为带上拉开漏输出
P2M3 = P2M3&0x0F|0x80; //SMG_A P27 推挽输出
P0M3 = P0M3&0x0F|0x80; //SMG_B P07 推挽输出
P0M1 = P0M1&0xF0|0x08; //SMG_C P02 推挽输出
P0M0 = P0M0&0xF0|0x08; //SMG_D P00 推挽输出
P1M0 = P1M0&0x0F|0x80; //SMG_E P11 推挽输出
P2M1 = P2M1&0xF0|0x08; //SMG_F P22 推挽输出
P0M1 = P0M1&0X0F|0x80; //SMG_G P03 推挽输出
// P0M0 = P0M0&0x0F|0x80; //SMG_DP P01 推挽输出
P1M0 = P1M0&0XF0|0x09; //SMG_COM1 P10 推挽输出
P2M0 = P2M0&0x0F|0x90; //SMG_COM2 P21 推挽输出
P0M3 = P0M3&0XF0|0x09; //SMG_COM3 P06 推挽输出
P0M2 = P0M2&0xF0|0x09; //SMG_COM4 P04 推挽输出
P0M0 = P0M0&0x0F|0x80; // PWM_OUT 推挽输出
//数码管COM端口初始化为高电平 不点亮
SMG_COM1 = 1;
SMG_COM2 = 1;
SMG_COM3 = 1;
SMG_COM4 = 1;
}
void SMG_Array(unsigned char i)
{
switch(i)
{
case 0:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_E = 1;
Delay_2us(100);
SMG_E = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
break;
case 1:
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
break;
case 2:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_E = 1;
Delay_2us(100);
SMG_E = 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G= 0;
Delay_2us(100);
break;
case 3:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G= 0;
Delay_2us(100);
break;
case 4:
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
break;
case 5:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
break;
case 6:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_E = 1;
Delay_2us(100);
SMG_E = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G= 0;
Delay_2us(100);
break;
case 7:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
break;
case 8:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_E = 1;
Delay_2us(100);
SMG_E = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G= 0;
Delay_2us(100);
break;
case 9:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_G = 1;
Delay_2us(100);
SMG_G = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
break;
case 10:
SMG_A = 1;
Delay_2us(100);
SMG_A = 0;
Delay_2us(100);
SMG_B = 1;
Delay_2us(100);
SMG_B = 0;
Delay_2us(100);
SMG_C = 1;
Delay_2us(100);
SMG_C = 0;
Delay_2us(100);
SMG_D = 1;
Delay_2us(100);
SMG_D = 0;
Delay_2us(100);
SMG_E = 1;
Delay_2us(100);
SMG_E = 0;
Delay_2us(100);
SMG_F = 1;
Delay_2us(100);
SMG_F= 0;
Delay_2us(100);
break;
}
}
void SMG_Display(unsigned int i)
{
unsigned char Qian, Bai, Shi, Ge;
Qian = i/1000;
Bai = i%1000/100;
Shi = i%100/10;
Ge = i%10;
SMG_COM1 = 0;
SMG_COM2 = 1;
SMG_COM3 = 1;
SMG_COM4 = 1;
switch(Qian)
{
case 0:
SMG_Array(Qian);
break;
case 1:
SMG_Array(Qian);
break;
case 2:
SMG_Array(Qian);
break;
case 3:
SMG_Array(Qian);
break;
case 4:
SMG_Array(Qian);
break;
case 5:
SMG_Array(Qian);
break;
case 6:
SMG_Array(Qian);
break;
case 7:
SMG_Array(Qian);
break;
case 8:
SMG_Array(Qian);
break;
case 9:
SMG_Array(Qian);
break;
}
SMG_COM1 = 1;
SMG_COM2 = 0;
SMG_COM3 = 1;
SMG_COM4 = 1;
switch(Bai)
{
case 0:
SMG_Array(Bai);
break;
case 1:
SMG_Array(Bai);
break;
case 2:
SMG_Array(Bai);
break;
case 3:
SMG_Array(Bai);
break;
case 4:
SMG_Array(Bai);
break;
case 5:
SMG_Array(Bai);
break;
case 6:
SMG_Array(Bai);
break;
case 7:
SMG_Array(Bai);
break;
case 8:
SMG_Array(Bai);
break;
case 9:
SMG_Array(Bai);
break;
}
SMG_COM1 = 1;
SMG_COM2 = 1;
SMG_COM3 = 0;
SMG_COM4 = 1;
switch(Shi)
{
case 0:
SMG_Array(Shi);
break;
case 1:
SMG_Array(Shi);
break;
case 2:
SMG_Array(Shi);
break;
case 3:
SMG_Array(Shi);
break;
case 4:
SMG_Array(Shi);
break;
case 5:
SMG_Array(Shi);
break;
case 6:
SMG_Array(Shi);
break;
case 7:
SMG_Array(Shi);
break;
case 8:
SMG_Array(Shi);
break;
case 9:
SMG_Array(Shi);
break;
}
SMG_COM1 = 1;
SMG_COM2 = 1;
SMG_COM3 = 1;
SMG_COM4 = 0;
switch(Ge)
{
case 0:
SMG_Array(Ge);
break;
case 1:
SMG_Array(Ge);
break;
case 2:
SMG_Array(Ge);
break;
case 3:
SMG_Array(Ge);
break;
case 4:
SMG_Array(Ge);
break;
case 5:
SMG_Array(Ge);
break;
case 6:
SMG_Array(Ge);
break;
case 7:
SMG_Array(Ge);
break;
case 8:
SMG_Array(Ge);
break;
case 9:
SMG_Array(Ge);
break;
}
}
/*********************************主程序*************************************************/
void main()
{
SystemInit();
GpioInit();
while(1)
{
ADCC0 |= 0x40; //启动ADC转换
while(!(ADCC0&0x20)); //等待ADC转换结束
ADCC0 &=~ 0x20; //清除标志位
gui_AdcValue = ADCR; //获取ADC的值
if(gui_AdcValue1>820)
{
//ADC值最大4096 显示值最大2500 4096/2500=1.6384
//数码管显示值在500——2500之间
SMG_Display(gui_AdcValue1=gui_AdcValue/1.6384);
//占空比计算= 0x0FA0 / (Fosc / PWM分频系数) (Fosc见系统时钟配置的部分)
// = 0x0155 / (16000000 / 128)
// = 312 / 125000
// = 2500us 占空比为 2000/200000 = 1%
//2500us 占空比计算值=312 4096/312=13.128
// 如:我需要2000us
// 通过↑公式计算 占空比计算值=250 实际ADC值=250乘以13.128=3282
gui_AdcValue2=gui_AdcValue/13.128;
PWM0DH = gui_AdcValue2>>8; //PWM0高4位占空比0x0F
PWM0DL = gui_AdcValue2; //PWM0低8位占空比0xA0
}
else //ADC值小于820, 820/1.6384=500 数码管直接锁定显示500
{
SMG_Display(gui_AdcValue1=820);
}
};
}
2020-03-7 :程序修改
|