STC12C5A60S2单片机各个模块程序代码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//********************************************************************** ******// // STC12C5A60S2可编程时钟模块
//
////********************************************************************
********//
#include <STC12C5A60S2.H>
#include <intrins.h>
//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句 //若想测试CLKOUT1和CLKOUT0请注释此句
#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*/
//*********************************//
}
#else /*条件编译CLKOUT0时钟输出*/
//*********************************//
// CLKOUT0时钟和CLKOUT1初始化 //
//*********************************//
void CLKOUT_init(void)
{
WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0 //T0工作在1T模式时的输出频率 =
SYSclk/(256-TH0)/2


AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式

//T1定时器速度是普通8051的12倍,即工作在1T模式

TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数 //定时器1工作模式为方式2,自动装载时间常数
TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频
TL0 = 0xff;
TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频
//**********************************************************************
******//
// STC12C5A60S2系统时钟模块
//
//
// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶
体时钟
// 出厂标准配置是使用外部晶体或时钟
//
4、8、
#include <intrins.h>
#define Bus_clk 12 //若要修改系统时钟直接在此处修改
//12 为 12M 的sysclk
//6 为 6M 的sysclk
//3 为 3M 的sysclk //1500 为 1.5M 的sysclk //750 为 750kHz 的sysclk //375 为 375kHz 的sysclk //187500 为 187.5kHz 的sysclk
CLK_DIV = 0x01;
#elif( Bus_clk == 3 )
CLK_DIV = 0x02;
#elif( Bus_clk == 1500 )
CLK_DIV = 0x03;
#elif( Bus_clk == 750 )
CLK_DIV = 0x04;
#elif( Bus_clk == 375 )
CLK_DIV = 0x05;
#elif( Bus_clk == 187500 )
//**********************************************************************
******//
// STC12C5A60S2系统省电模块
//
//
// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速
模式
// 掉电模式
//
)
#define uint unsigned int
uchar Power_Down_Flag = 0; //进入掉电状态标志sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯
sbit Power_Down_LED_INT0 = P0^1; //INT0口掉电唤醒指示灯sbit N_Power_Down_LED_INT0 = P0^2; //INT0口没有唤醒指示灯sbit Normal_Work_LED = P0^3; //正常工作指示灯sbit Power_Down_Wakeup_INT0= P3^2; //外中断唤醒输入口
for( t = 0; t < 82; t++ );
}
}
//***********************************//
// 正常工作指示
//***********************************// void Normal_work(void)
{
Normal_Work_LED = 1;
Delay_ms(500);
}
//***********************************// // 中断初始化 // //***********************************// void Intp_init(void)
{
IT0 = 0; //外部中断源0为低电平触发 EX0 = 1; //允许外部中断
EA = 1; //开总中断
}
wakeup_counter++;
for( j = 0; j < 250; j++ )
{
Normal_work(); //系统正常工作指示
}
Power_Down_Flag = 1; //系统开始进入掉电状态
PCON = 0x02;
_nop_();
_nop_();
_nop_();
while( Power_Down_Wakeup_INT0 == 0 )
{
_nop_(); //等待高电平
}
Power_Down_LED_INT0 = 0;
}
else //未掉电状态
{
N_Power_Down_LED_INT0 = 1; //不是掉电唤醒指示
while( Power_Down_Wakeup_INT0 == 0 )
//
//
// 说明: STC12C5A60S2单片机有8路10位高速AD转换器,P1^0-P1^7
//
// 涉及寄存器:P1ASF(模拟功能控制寄存器)、ADC_CONTR(ADC控制寄存器)
// ADC_RES、ADC_RESL(转换结果寄存器)
//
// 注意: 1、初次打开内部A/D模拟电源需适当延时等内部模拟电源稳定后,
再启动A/D转换
// 启动A/D后,在转换结束前不改变任何I/O口的状态,有利于高精
#include <STC12C5A60S2.h>
#include <intrins.h>
#include "lcd.h"
#define ADC_POWER 0x80 //AD电源控制
#define ADC_START 0x08 //AD转换控制
#define ADC_FLAG 0x10 //AD转换完成
#define Speed_0 0x00 //540 clk
#define Speed_1 0x20 //360 clk
#define Speed_2 0x40 //180 clk
// A/D初始化//
//**********************************//
void AD_init(void)
{
AUXR1 = 0x04; //转换结果高2位放在ADC_RES的低2
位中,低8位放在ADC_RESL中
P1ASF = 0x01; //P1.0口作为模拟功能A/D使用 ADC_RES = 0x00; //结果清零
ADC_RESL = 0x00;
ADC_CONTR = ADC_POWER|Speed_2|ADC0|ADC_START; //打开电源,180CLK周
// 串口初始化 //
//****************************************//
void UART_init(void)
{
SM0 = 0; //选择串口为方式1工作
SM1 = 1; //8位数据波特率可变
REN = 1;
BRT = 0xDC;
AUXR = 0x15; //选择独立波特率发生器为串行 //口的波特率发生器,模式为1T
// 串口发送数据// //******************************************// void SendData( uchar byte )
{
SBUF = byte;
while(!TI);
TI = 0;
}
//******************************************//
// 主程序//
ADC_CONTR &= !ADC_FLAG; //清标志
Printf_Decimal(Result_Calculate());
ADC_RES = 0x00;
ADC_RESL = 0x00;
ADC_CONTR = ADC_POWER|Speed_2|ADC_START; //开始下一次转换
_nop_();
_nop_();
_nop_();
_nop_();
}
uchar Read_Date(void); //读数据
void Write_Cmd( uchar cmd ); //写命令
void Write_Date( uchar date );//写数据
void Init_LCD(void);//初始化LCD
void Location( uchar x, uchar y );//设定显示位置
void Clear_Screen(void);//清屏
void Write_str( uchar *p );
void Printf_Decimal(double Num);
#include "lcd.h"
for( t = 0; t < 41; t++ );
}
}
//**********************************//
//* 名称: Busy()
//* 功能: 读取忙状态
//* 输入: 无
//* 输出: 1-忙 0-空闲
//**********************************//
uchar Busy(void)
//* 功能: 读12864状态
//* 输入: 无
//* 输出: status-当前状态
//**********************************// uchar Read_Status(void)
{
uchar status;
RS = 0;
RW = 1;
E = 0;
//* 名称: Write_Cmd()
//* 功能: 向12864写命令
//* 输入: cmd - 命令参数
//* 输出: 无
//**********************************//
void Write_Cmd( uchar cmd )
{
RS = 0;
RW = 0;
//**********************************// void Write_Date( uchar date )
{
while(Busy());
RS = 1;
E = 0;
_nop_();
_nop_();
P2 = date;
uchar Read_Date(void)
{
uchar date;
while(Busy()); //忙
RS = 1;
E = 0;
_nop_();
_nop_();
_nop_();
//**********************************// void Init_LCD(void)
{
Delay_ms(4);
PSB = 1;//并行方式
Delay_ms(4);
Write_Cmd(0x0c);//开显示关游标
Delay_ms(4);
Clear_Screen();//清屏
}
else if( x == 2 )
x = 0x90;
else if( x == 3 )
x = 0x88;
else if( x == 4 )
x = 0x98;
position = x + y;
Write_Cmd(position);
Delay_ms(2);
}
Delay_ms(10);
}
//**********************************// //* 名称: Write_str()
//* 功能: 向12864里写字符串
//* 输入: *p -- 字符串地址
//* 输出: 无
//**********************************// void Write_str( uchar *p )
{
{
uchar s[6] = {0,0,46,0,0};
uint t;
t = (uint)(Num * 1000);
s[0] = t/10000+48;
s[1] = t%10000/1000+48;
s[3] = t%1000/100+48;
s[4] = t%100/10+48;
s[5] = t%10+48;
Location(1,2);
// STC12C5A60S2 PCA/PWM模块
//
//
// 说明: STC12C5A60S2单片机有两路可编程计数器阵列(PCA)模块,可用于
软件
// 定时器,外部脉冲的捕捉、高速输出以及脉宽调制(PWM)输出
//
// 涉及寄存器:CMOD(PCA工作模式寄存器) CCON(PCA控制寄存器) // CCAPM0,CCAPM1(PCA比较/捕获寄存器)
// CH,CL(PCA的16位计数器)、CCAPnL,CCAPnH(PCA捕捉/比较
********//
#include <STC12C5A60S2.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/*******高速模式变量更改*********/
#define FOSC 12000000
#define T100KHz (FOSC/2/100000) //高速脉冲输出频率计算: f = PCA模块
的时钟源/(2*CCAP0L)
//CCAP0L = PCA时钟源/2/f
)
#define CLK_6 0x0d //Sysclk/6
#define CLK_8 0x0e //Sysclk/8
/********模式选择********/
#define H_model 0x4d //高速输出模式,中断模式
#define T_model 0x49 //定时模式
#define P_model 0x42 //无中断PWM模式
#define PL_model 0x63 //由低变高可中断PWM模式#define PH_model 0x53 //由高变低可中断PWM模式#define PHL_model 0x73 //高低都可中断PWM模式
#define CU_model 0x61 //16位捕获,上升触发中断模式
//********************************//
// H_model初始化 //
//********************************//
void HP_init(void)
{
CMOD = CLK_4; //PCA时钟源为Sysclk
CCAPM0 = H_model; //高速输出模式
CCAP0L = value;
CCAP0H = value>>8;
value += T100KHz;
CR = 1; //开启PCA计数器
//当不使用定时0溢出为时钟源时,PWM输出的频率=PCA的
时钟源/256
//使用定时器溢出的时钟源时,可设定定时器的值对输出
频率的改变
//分频为0-256分频
}
//********************************// // T_model初始化 // //********************************//
void CD_init(void)
{
CMOD = CLK_4;
CCAPM0 = CD_model;
CR = 1;
EA = 1;
}
//********************************// // 主程序 // //********************************//
//*******************************// void CD_Service(void) interrupt 7
{
CCF0 = 0;
LED = ~LED;
/*void TP_Service(void) interrupt 7
{
CCF0 = 0; //清除PCA计数器溢出中断标志
test++;
CCAP0L = value;
CCAP0H = value>>8;
value += T100KHz;
} */
//**********************************************************************
******//
// STC12C5A60S2串行通信模块
// IP(中断优先级寄存器)IPH()SADEN()SADDR()WAKE_CLKO(时
钟唤醒寄存器)
// Bit1 - PD 控制单片机进入掉电模式
// //
// 程序说明:程序实现从PC端发送数据到单片机,单片机将接收到的数据
通过12864
// 显示出来
//
//**********************************************************************
******//
时需修
//波特率为19200
uchar Send_Bflag = 0; //正在发送标志
uchar Receive_Bflag = 0; //正在接送标志
uchar Re;
sbit LED = P1^4;
sbit LED1 = P1^5;
void UART_init(void);
void Delay( uint time );
#elif( BTL == 4800 )
BRT = 0xB8;
#elif( BTL == 9600 )//波特率设置为9600
BRT = 0xDC;
#elif( BTL == 14400 )
BRT = 0xE8;
#elif( BTL == 19200 )
BRT = 0xEE;
#elif( BTL == 28800 )
BRT = 0xF4;
}
//************************************************// // 发送一个字节数据 // //************************************************// void Send_byte( uchar byte )
{
SBUF = byte;
while(!TI);
TI = 0;
// 接收函数 // //************************************************//
void Receive( void )
{
Write_Date(SBUF);
Re++;
if( Re == 16 )Location(2,0); if( Re == 32 )Location(3,0); if( Re == 48 )Location(4,0);
if( Re == 66 )
UART_init();
while(1)
{
if( RI == 1 )
{
RI = 0;
Receive();
Printf("Success!");
}
EA = 1;
}
//**********************************************************************
******//
// STC12C5A60S2 SPI接口模块
//
//


#include <STC12C5A60S2.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/************对SPCTL寄存器的设置位宏定义*************/
#define SSIG 0x80 //SS引脚忽略
#define SPEN 0x40 //SPI使能位
#define DORD 0x20 //SPI数据发送LSB最先发送
#define MSTR 0x10 //主从模式选择
/************串口波特率设定*************************/
#define BTL 9600 //若要更改波特率直接更改此处,当波特率大于9600时需修
改相应的接收程序,
//可选波特率有以下: 否则有可能出现乱码
//波特率为2400 //波特率为28800
//波特率为4800 //波特率为38400 //波特率为9600 //波特率为57600 //波特率为14400 //波特率为115200
//波特率为19200
void UART_init(void);
#if( BTL == 2400 )
BRT = 0x70; //波特率设置为9600 #elif( BTL == 4800 )
BRT = 0xB8;
#elif( BTL == 9600 )
BRT = 0xDC;
#elif( BTL == 14400 )
BRT = 0xE8;
#elif( BTL == 19200 )
BRT = 0xEE;
// IP = 0X10; //PS = 1;串口1中断为最高优先级中断// EA = 1; //开总中断
}
//************************************************// // 发送一个字节数据 //
//************************************************// void Send_byte( uchar byte )
{
SBUF = byte;
while(!TI);
//************************************************// // 接收函数 // //************************************************//
uchar Receive( void )
{
uchar byte;
_nop_();
_nop_();
_nop_();
_nop_();
//***********************************//
void Init_SPI(void)
{
SPDAT = 0; //清空数据寄存器 SPSTAT = SPIF|WCOL; //清空SPI状态寄存器
SPCTL = SPEN|MSTR; //SPI设置为主机模式
IE2 = 0x02; //允许SPI中断
}
//***********************************//
//* 名称:main
if(flag) //当PC端有发送数据时才进行SPI传输数据
{
SPISS = 0;
SPDAT = flag;
flag = 0;。

相关文档
最新文档