深圳市赛元微电子股份有限公司工具与软件/软件开发工具/下载KEIL(C51)插件安装包SOC_KEIL_Setup并安装,自动安装到KEIL C51安装路径(先安装KEIL C51软件),安装成功后在Keil C51软件安装目录下就会有赛元SOC 51单片机DEMO示例。

SOC_KEIL_Setup V1.40(LIB0D29) KEIL 插件V1.40中文rar7.2MB2023-11-22下载

 

 

初始化

建议使用位运算可以更方便得使某一位寄存器位bit置1或置0而不影响同寄存器其他位bit

以SC92F73A3_73A2_73A1_Demo_Code为例

1、IO口初始化(配置PxCON、PxPH寄存器)

P0CON = 0xF0;//二进制11110000,表示管脚P0.0到P0.3为输入模式,P0.4到P0.7为强推挽输出模式,想要输入模式对应管脚置0,输入模式对应管脚置1

P0PH  = 0xF0;//二进制11110000,表示管脚P0.0到P0.3为高阻输入模式,P0.4到P0.7为上拉电阻打开模式(仅在管脚输入模式时有效),想要高阻输入模式对应管脚置0,上拉电阻打开模式对应管脚置1

IO口初始化有强推挽输出模式,带上拉输入模式,高阻输入模式,错误配置会导致ADC输入数据不准确,IO口无法检测高低电平,无法输出高低电平,无法进入外部中断等问题。

#include "H/Function_Init.H"

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

*函数名称:void IO_Init(void)

*函数功能:IO初始化

*入口参数:void

*出口参数:void

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

void IO_Init(void)

{

#if (IC_MODEL == SC92F73A3) //SC92F73A3脚定义

P0CON = 0x00; //设置P0为高阻输入模式

P0PH = 0x00;

P1CON = 0x00; //设置P1为高阻带上拉模式

P1PH = 0xFF;

P2CON = 0xFF; //设置P2为强推挽模式

P2PH = 0x00;

P5CON = 0xFF; //设置P4为强推挽模式

P5PH = 0x00;

#endif

#if (IC_MODEL == SC92F73A2) //SC92F73A2脚定义

P0CON = 0x00; //设置P0为高阻输入模式

P0PH = 0x00;

P1CON = 0x00; //设置P1为高阻带上拉模式

P1PH = 0xFF;

P2CON = 0xFF; //设置P2为强推挽模式

P2PH = 0x00;

SC92F73A2_NIO_Init(); //未引出IO口配置

#endif

#if (IC_MODEL == SC92F73A1) //SC92F73A1脚定义

P0CON = 0x00; //设置P0为高阻输入模式

P0PH = 0x00;

P1CON = 0x00; //设置P1为高阻带上拉模式

P1PH = 0xFF;

P2CON = 0xFF; //设置P2为强推挽模式

P2PH = 0x00;

SC92F73A1_NIO_Init(); //未引出IO口配置

#endif

}

2、外部中断初始化(配置IE、IP、INTxF、INTxR)

 IE = 0xFF;//二进制11111111,表示EA=1 中断使能总控制打开,EADC=1 ADC转换完成时产生中断,ET2=1 允许TIMER2中断,EUART=1 允许UART中断,ET1=1 允许TIMER1中断,EINT1=1 允许外部中断1中断,ET0=1 允许TIMER0中断,EINT0=1 允许外部中断0中断。

 IP=0xB8;//二进制10111000,表示IPT2=1 TIMER2优先级高,IPUART=1 UART优先高,IPT1=1 TIMER1优先级高。

INT0F = 0x02;//二进制00000010,表示INT0F1=1 INT0的通道1外部下降沿中断使能使用对应中断函数void EX0() interrupt 1{}

#include "H/Function_Init.H"

void EX_Init(void);

uchar INT1_flag = 0x00;

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

*函数名称:void EXTI_Test(void)

*函数功能:外部中断测试

*入口参数:void

*出口参数:void

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

void EXTI_Test(void)

{

EX_Init();

while(1)

{

}

}

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

*函数名称:void EX_Init(void)

*函数功能:外部中断初始化

*入口参数:void

*出口参数:void

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

void EX_Init(void)

{

//配置中断口INT03(P13)、INT12/13(P16/17)、INT24/25(P20/21)

P1CON &= 0X37; //中断IO口设置为高阻输入

P1PH |= 0xC8; //中断IO口设置为高阻带上拉

P2CON &= 0XFC; //中断IO口设置为高阻输入

P2PH |= 0x03; //中断IO口设置为高阻带上拉

//配置INT03上升沿中断、INT12/13下降沿中断、INT24/25双沿中断

//下降沿设置

INT0F = 0X00 ; //xxxx 0000 0关闭 1使能

INT1F = 0X0C ; //xxxx xxxx 0关闭 1使能

INT2F = 0X30 ; //0000 xxxx 0关闭 1使能

//上升沿设置

INT0R = 0X08 ; //xxxx 0000 0关闭 1使能

INT1R = 0X00 ; //xxxx xxxx 0关闭 1使能

INT2R = 0X30 ; //0000 xxxx 0关闭 1使能

//外部中断优先级设置

IE |= 0x05; //0000 0x0x

IE1 |= 0x08; //0000 x000 INT2使能

IP |= 0X00;

IP1 |= 0X00;

EA = 1;

}

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

*函数名称:void EX0/1/2() interrupt 0/2/10

*函数功能:外部中断函数

*入口参数:void

*出口参数:void

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

void EX0() interrupt 0

{

P24 = ~P24;

}

void EX1() interrupt 2

{

P25= ~P25;

if(P16 == 0)

{

INT1_flag = 0x10; //INT12产生中断

}

if(P17 == 0)

{

INT1_flag = 0x20; //INT13产生中断

}

}

void EX2() interrupt 10

{

P26 = ~P26;

}

3、定时器初始化(配置TMCON、TCON、TMOD、THx、TLx)

fsys系统频率可在烧录器配套软件窗口选择频率,主要为MCU内部RC振荡器分频。

#include "H/Function_Init.H"

void Timer_Init(void);

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

*函数名称:void Timer_Test(void);

*函数功能:T0/T1/T2测试

*入口参数:void

*出口参数:void

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

void Timer_Test(void)

{

Timer_Init();

while(1)

{

}

}

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

*函数名称:void Timer_Init(void)

*函数功能:T0/T1/T2初始化

*入口参数:void

*出口参数:void

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

void Timer_Init(void)

{

TMCON = 0X07; //------111 ;Timer0、Tiemr1和Tiemr2选择时钟Fsys

//T0设置

TMOD |= 0x01; //0000 0001;Timer0设置工作方式1

TL0 = (65536 - 16000)%256; //溢出时间:时钟为Fsys,则16000*(1/Fsys);

TH0 = (65536 - 16000)/256;

TR0 = 0;

ET0 = 1;//定时器0允许

TR0 = 1;//打开定时器0

//T1设置

TMOD |= 0x20; //0010 0000;Timer1设置工作方式2

TL1 = 256 - 160; //溢出时间:时钟为Fsys,则160*(1/Fsys);

TH1 = 256 - 160;

TR1 = 0;

ET1 = 1;//定时器1允许

TR1 = 1;//打开定时器1

//T2设置

T2MOD = 0x00;

T2CON = 0x00; //设置为16位重载寄存器

RCAP2H = (65536-32000)/256; //溢出时间:时钟为Fsys,则32000*(1/Fsys);

RCAP2L = (65536-32000)%256;

TR2 = 0;

ET2 = 1;//定时器2允许

TR2 = 1;//打开定时器2

/*

//Timer2捕获功能

T2CON = 0X09; //使能EXT2,16位捕获模式

T2MOD = 0X00;

TH2 = 0X00;

TL2 = 0X00;

RCAP2H = 0X00;

RCAP2L = 0X00;

TR2 = 0;

ET2 = 1;//定时器2允许

TR2 = 1;//打开定时器2

*/

EA = 1;

}

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

*函数名称:void timer0/1/2() interrupt 1/3/5

*函数功能:定时器中断产生方波

*入口参数:void

*出口参数:void

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

void timer0() interrupt 1

{

TL0 = (65536 - 16000)%256;

TH0 = (65536 - 16000)/256;

P24 = ~P24;

}

void timer1() interrupt 3

{

P25 = ~P25;

}

void Timer2Int(void) interrupt 5

{

TF2 = 0; //溢出清零

P26 = ~P26;

}

4、ADC初始化(配置ADCCON、ADCCFG0、ADCCFG1、ADCCFG2)

 

#include "H/Function_Init.H"

void ADC_Init(uint Channel,uchar ADCFreq);

unsigned int ADCValue = 0x0000;

bit AdcFlag = 0;

/***********ADC采样频率选择*************/

enum ADCFreq {F32=0,F24,F16,F12,F8,F6,F4,F3};

/***********ADC采样口选择*************/

#if (IC_MODEL == SC92F73A3)

enum Channel {AIN0=0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,VDD4=31};

#endif

#if (IC_MODEL == SC92F73A2)

enum Channel {AIN2=2,AIN3,AIN4,AIN5,AIN8=8,AIN9,VDD4=31};

#endif

#if (IC_MODEL == SC92F73A1)

enum Channel {AIN3=3,AIN4,AIN8=8,AIN9,VDD4=31};

#endif

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

*函数名称:void ADC_Test(void)

*函数功能:ADC测试

*入口参数:void

*出口参数:void

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

void ADC_Test(void)

{

ADC_Init(AIN3,F8);

while(1)

{

ADCCON |= 0X40; //开始ADC转换

while(!AdcFlag); //等待 ADC转换完成;

AdcFlag = 0;

ADCValue=(ADCVH<<4)+(ADCVL>>4);

}

}

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

*函数名称:void ADC_Init(uint Channel,uchar ADCFreq)

*函数功能:ADC初始化

*入口参数:void

*出口参数:void

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

void ADC_Init(uint Channel,uchar ADCFreq)

{

ADCCON = 0X80|Channel; //开启ADC,ADC采样频率为2M ,选择Channel位ADC采样口

if(Channel<8)

{

ADCCFG0 = 1<

}

else

{

ADCCFG1 = 1<<(Channel-8); //设置Channel作为采样口

}

ADCCFG2 = ADCFreq;

IE |= 0X40; //开启ADC中断

EA = 1;

}

void ADC_Interrupt(void) interrupt 6

{

ADCCON&=~(0X20); //清中断标志位

AdcFlag = 1;

}

5、PWM初始化(配置PWMCFG、PWMCON、PWMPRD、PWMDTYx)

#include "H/Function_Init.H"

void PWM_Init(void);

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

*函数名称:void PWM_Test(void)

*函数功能:PWM测试

*入口参数:void

*出口参数:void

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

void PWM_Test(void)

{

PWM_Init();

while(1)

{

}

}

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

*函数名称:void PWM_Init(void)

*函数功能:PWM初始化

*入口参数:void

*出口参数:void

*注意:周期与占空比的低2位要先写值,再写高8位

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

void PWM_Init(void)

{

PWMCFG = 0x00; //设置PWM系统时钟,控制输出反向

PWMCON = 0X3f; //控制是否输出到IO口

PWMDTYA = 0xea; //周期与PWM0/1/2占空比的低2位设置

PWMPRD = 0x4f; //周期高8位设置

PWMDTY0 = 0x28; //PWM0占空比高8位设置

PWMDTY1 = 0x28; //PWM1占空比高8位设置

PWMDTY2 = 0x28; //PWM2占空比高8位设置

PWMDTYB = 0X00; //PWM3/4/5周期与占空比的低2位设置

PWMDTY3 = 0X14; //PWM3占空比高8位设置

PWMDTY4 = 0X14; //PWM4占空比高8位设置

PWMDTY5 = 0X14; //PWM5占空比高8位设置

PWMCON |= 0x80; //打开PWM使能端

IE1 |= 0x02;

EA = 1;

}

/*

void PWM_Dead(void) //死区设置

{

PWMCFG = 0X38; //设置PWM系统时钟,控制输出反向

PWMCON = 0X3F; //控制是否输出到IO口

PWMDTYB |= 0X80; //设置死区模式

PWMPRD = 0X18; //周期高8位设置

PWMDTYA = 0XEA; //11 10 10 10 周期与占空比低2位

PWMPRD = 0X18; //周期与PWM0/1/2占空比的低2位设置

PWMDTY0 = 0X0C; //PWM0占空比高8位设置

PWMDTY1 = 0X10; //PWM1占空比高8位设置

PWMDTY2 = 0X0C; //PWM2占空比高8位设置

PWMDTY3 = 0X00; //死区时间设置

PWMCON |= 0X80; //开PWM

}

*/

void PWMInt(void) interrupt 8

{

P00=~P00;

}

6、内部IAP(EEPROM)使用

#define IapROM  0x00 #define IapEPPROM  0x02

IAPWrite(0x7F,Date_num,IapEPPROM);//存入的数据Date_num

Date=IAPRead(0x7F,IapEPPROM);//读取数据Date

IAPWrite、IAPRead不要频繁操作,只有<=10万次写入操作。

#include "H/IAP_Init.H"

unsigned char code *IapAddr = 0x00;

void IAPWrite(uint Addr,INT8S Value,uchar IAPArea);

INT8S IAPRead(uint Addr,uchar IAPArea);

uchar IapReadData = 0x00;//存放读取的IAP数据

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

*函数名称:void IAPWrite(uchar Addr,uchar Value,uchar IAPArea)

*函数功能:IAP写初始化

*入口参数:Addr,Value,IAPArea

*出口参数:void

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

void IAPWrite(uint Addr,INT8S Value,uchar IAPArea)

{

EA = 0;

IAPDAT = Value;//写入数据Data

IAPADH = ((Addr>>8)&0X7F);//写入地址的高5位

IAPADL = Addr;//写入地址的低8位

IAPADE = IAPArea;//IAPArea=0x00:选择ROM区操作 IAPArea=0x02:选择EEPROM区操作

IAPKEY = 240;//IAP开启保护控制时间

IAPCTL = 0x06;//CPU hold time为2ms,写入操作命令

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

IAPADE = 0x00;//MOVC指向ROM

EA = 1;

}

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

*函数名称:uchar IAPRead(uchar Addr,uchar IAPArea)

*函数功能:IAP读初始化

*入口参数:Addr,IAPArea

*出口参数:ReadValue

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

INT8S IAPRead(uint Addr,uchar IAPArea)

{

uchar ReadValue = 0x00;

EA = 0;

IAPADE = IAPArea;

ReadValue = *(IapAddr+Addr);//读取的数据

IAPADE = 0x00;//MOVC指向ROM

EA = 1;

return ReadValue;

}

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。