当前位置:文档之家› STC12C5A60S2单片机c语言程序代码调试例程

STC12C5A60S2单片机c语言程序代码调试例程

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

// STC12C5A60S2可编程时钟模块

//

//

// 说明:STC12C5A60S2单片机有三路可编程时钟输出CLKOUT0/T0/P3.4

// CLKOUT1/T1/P3.5、CLKOUT2/P1.0

//

// 涉及寄存器:AUXR(辅助寄存器)、WAKE_CLKO(时钟与系统掉电唤醒控制寄存

器)

// BRT(独立波特率发生器定时器寄存器)

//

// 程序说明:

// 本程序可选实现P3.4输出CLKOUT0时钟、P3.5输出CLKOUT1时



// P1.0输出CLKOUT2时钟

//

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

/

#include

#include

//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句

//若想测试CLKOUT1和CLKOUT0请注释此句

#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*/

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

// CLKOUT2时钟初始化 //

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

void CLKOUT_init(void)

{

WAKE_CLKO = 0x04; //Bit2-BRTCLKO 允许P1.0配置为独立波特率发生器的时

钟输出

//BRT工作在1T模式下时的输出频率 = Sysclk/(256-BRT)/2

//BRT工作在12T模式下时输出频率 = Sysclk/12/(256-BRT)/2

AUXR = 0x14; //Bit4-BRTR 允许独立波特率发生器运行

//Bit2-BRTx12 BRT工作在1T模式下

BRT = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频

}

#else /*条件编译CLKOUT0时钟输出*/

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

// CLKOUT0时钟和CLKOUT1初始化 //

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

void CLKOUT_init(void)

{

WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0

//T0工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2

//T0工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2

//1T指的是每1个时钟加1,是普通C51的12倍

//12T指的是每12个时钟加1与普通C51一样

//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只

能工作在定时器模式2下

//T1工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2

//T1工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2

//1T指的是每1个时钟加1,是普通C51的12倍

//12T指的是每12个时钟加1与普通C51一样

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

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

TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数

//定时器1工作模式为方式2,自动装载时间常数

TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频

TL0 = 0xff;

TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频

TL1 = 0xff;

TR1 = 1;

TR0 = 1;

}

#endif

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

// 主程序 //

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

//

void main()

{

CLKOUT_init();

while(1);

}

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

// STC12C5A60S2系统时钟模块

//

//

// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时



// 出厂标准配置是使用外部晶体或时钟

//

//

// 涉及寄存器:CLK_DIV(时钟分频寄存器)

// 由该寄存器的Bit0-2组合可实现对时钟源进行0、2、4、8、16

// 32、64、128分频

// //

// 程序说明:

// 对外部时钟进行分频得到Sysclk,然后经过P1.0的独立波特率

// 时钟输出功能Sysclk/2输出时钟频率

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

#include

#include

#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

//93750 为 93.75kHz 的sysclk

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

// 系统时钟初始化 //

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

void Sysclk_init(void)

{

WAKE_CLKO = 0x04; //配置P1.0口为频率输出

AUXR = 0x14; //允许波特率时钟工作

//工作模式为1T

BRT = 0xff;

#if( Bus_clk == 12 )

CLK_DIV = 0x00;

#elif( Bus_clk == 6 )

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 )

CLK_DIV = 0x06;

#elif( Bus_clk == 93750 )

CLK_DIV = 0x07;

#endif

}

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

// 主程序 //

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

void main()

{

Sysclk_init();

while(1);

}

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

// STC12C5A60S2系统省电模块 //

//

// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式

// 掉电模式

//

//

// 涉及寄存器:PCON(电源控制寄存器)

// Bit0 - IDL 控制单片机进入IDLE空闲模式

// Bit1 - PD 控制单片机进入掉电模式

// //

// 程序说明: 程序实现让单片机先工作一阵子(通过P0^3指示灯显示)

// 然后进入掉电状态,利用外部中断0口来唤醒单片机工作

// 唤醒后单片机将通过P0^0-3口的灯闪烁显示开始工作

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

/

#include

#include

#define uchar unsigned char

#define uint unsigned int

uchar Power_Down_Flag = 0; //进入掉电状态标志

sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯

sbi

t 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; //外中断唤醒输入口

void Delay_ms( uint time );

void Normal_work(void);

void Intp_init(void);

void After_Powr_Down(void);

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

// 软件延时 //

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

void Delay_ms( uint time )

{

uint t; //延时时间 = (time*1003+16)us while(time--)

{

for( t = 0; t < 82; t++ );

}

}

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

// 正常工作指示

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

void Normal_work(void)

{

Normal_Work_LED = 1;

Delay_ms(500);

Normal_Work_LED = 0;

Delay_ms(500);

}

void After_Power_Down(void)

{

uchar i ;

for( i = 0; i < 100; i++ )

{

P0 = 0x0f;

Delay_ms(500);

P0 = 0x00;

Delay_ms(500);

}

}

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

// 中断初始化 //

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

void Intp_init(void)

{

IT0 = 0; //外部中断源0为低电平触发

EX0 = 1; //允许外部中断

EA = 1; //开总中断

}

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

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

// 主程序 //

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

void main()

{

uchar j = 0;

uchar wakeup_counter = 0; //记录掉电次数

P0 = 0x00;

Chip_Start_LED = 1; //单片机开始工作

Intp_init(); //外中断0初始化

while(1)

{

P2 = wakeup_counter;

wakeup_counter++;

for( j = 0; j < 250; j++ )

{

Normal_work(); //系统正常工作指示

}

Power_Down_Flag = 1; //系统开始进入掉电状态

PCON = 0x02;

_nop_();

_nop_();

_nop_();

_nop_();

After_Power_Down(); //掉电唤醒后

}

}

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

// 中断服务

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

void INT0_Service(void) interrupt 0

{

if( Power_Down_Flag ) //掉电唤醒状态指示

{

Power_Down_Flag = 0;

Power_Down_LED_INT0 = 1;

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 )

{

_nop_();

}

N_Power_Down_LED_INT0 = 0;

}

}

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

// STC12C5A60S2 A/D转换模块 //

//

// 说明: 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口的状态,有利于高精度A/D转



// 若能将定时器/串行/中断系统关闭更好。

// 2、A/D转换模块使用的时钟为内部R/C振荡器所产生的系统时钟

// 3、由于使用两套时钟,设置好ADC_CONTR后要加4个空延时操作才可

以正确

// 读到ADC_CONTR寄存器的值

////

// 程序说明:

// 本程序实现P1^0口作为A/D采集输入口,对外部电压的测量并将测量

结果通过

// 12864和串口显示出来

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

/

#include

#include

#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

#define Speed_3 0x60 //90 clk

#define ADC0 0x00 //P1.0

#define ADC1 0x01 //P1.1

#define ADC2 0x02 //P1.2

#define ADC3 0x03 //P1.3

#define ADC4 0x04 //P1.4

#define ADC5 0x05 //P1.5

#define ADC6 0x06 //P1.6

#define ADC7 0x07 //P1.7

void AD_init(void);

double Result_Calculate(void);

void SendData( uchar byte );

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

// 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周期转换,选择P1.0作输入

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

EADC = 1; //允许A/D转换中断

EA = 1; //开总中断

}

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

// 串口初始化 //

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

void UART_init(void)

{

SM0 = 0; //选择串口为方式1工作

SM1 = 1; //8位数据波特率可变

REN = 1;

BRT = 0xDC;

AUXR = 0x15; //选择独立波特率发生器为串行

//口的波特率发生器,模式为1T

}

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

// 转换结果计算 //

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

double Result_Calculate(void)

{

uint temp;

double result;

temp = ADC_RES * 256 + ADC_RESL;

result = temp * 4.94 / 1024;

return result;

}

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

// 串口发送数据 //

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

void SendData( uchar byte )

{

SBUF = byte;

while(!TI);

TI = 0;

}

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

// 主程序 //

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

void main()

{

Init_LCD();

AD_init();

UART_init();

while(1);

}

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

// A/D中断服务 //

//*

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

void AD_Service(void) interrupt 5

{

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_();

}

#include

#include

#define uchar unsigned char

#define uint unsigned int

sbit PSB = P0^4; //串/并行接口选择 1-并行 0-串行

sbit RS = P0^7; //并行数据/命令选择,串行片选 0-指令 1-数据

sbit RW = P0^6; //并行读写选择 0-写 1-读 串行数据口

sbit E = P0^5; //并行使能, 串行同步时钟

void Delay_ms( uint time ); //延时

uchar Busy(void); //读忙

uchar Read_Status(void);//读状态

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"

extern void SendData( uchar byte );

/***********以下部分为LCD的驱动程序*************/

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

//* 名称: Delay_ms()

//* 功能: 实现软件延时

//* 输入: time - 时间参数

//* 输出: 无

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

void Delay_ms( uint time )

{

uint t; //82,延时时间 = (time*1003+16)us

while(time--) //41,延时时间 = (time*499+16)us

{

for( t = 0; t < 41; t++ );

}

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

}

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

//* 名称: Busy()

//* 功能: 读取忙状态

//* 输入: 无

//* 输出: 1-忙 0-空闲

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

uchar Busy(void)

{

uchar busy,flag;

Delay_ms(1);

busy = Read_Status();

if( busy & 0x80 )

flag = 1;

else

flag = 0;

Delay_ms(1);

return flag;

}

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

//* 名称: Read_Status()

//* 功能: 读12864状态

//* 输入: 无

//* 输出: status-当前状态

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

uchar Read_Status(void)

{

uchar status;

RS = 0;

RW = 1;

E = 0;

_nop_();

_nop_();

_nop_();

E = 1;

Delay_ms(1);

status = P2;

Delay_ms(1);

E = 0;

_nop_();

_nop_();

return status;

}

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

//* 名称: Write_Cmd()

//* 功能: 向12864写命令

//* 输入: cmd - 命令参数

//* 输出: 无

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

void Write_Cmd( uchar cmd )

{

RS = 0;

RW = 0;

E = 0;

Delay_ms(1);

P2 = cmd;

Delay_ms(1);//等待数据稳定

E = 1;

Delay_ms(1);

E = 0;

}

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

//* 名称: Write_Date()

//* 功能: 向12864写数据

//* 输入: date - 待写入的数



//* 输出: 无

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

void Write_Date( uchar date )

{

while(Busy());

RS = 1;

RW = 0;

E = 0;

_nop_();

_nop_();

P2 = date;

Delay_ms(1);//待数据稳定

E = 1;

Delay_ms(1);

E = 0;

_nop_();

_nop_();

}

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

//* 名称: Read_Date()

//* 功能: 向12864读数据

//* 输入: 无

//* 输出: date - 返回的数据

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

uchar Read_Date(void)

{

uchar date;

while(Busy()); //忙

RS = 1;

RW = 1;

E = 0;

_nop_();

_nop_();

_nop_();

E = 1;

Delay_ms(1);

date = P2;

Delay_ms(1);

E = 0;

_nop_();

return date;

}

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

//* 名称: Init_LCD()

//* 功能: 初始化LCD

//* 输入: 无

//* 输出: 无

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

void Init_LCD(void)

{

Delay_ms(4);

PSB = 1;//并行方式

Delay_ms(4);

Write_Cmd(0x0c);//开显示关游标

Delay_ms(4);

Clear_Screen();//清屏

}

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

//* 名称: Location()

//* 功能: 设定显示位置

//* 输入: x,y --X轴点 --Y轴点

//* x 只能是1-4中的一个数

//* Y 只能是0-7中的一个数

//* 输出: 无

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

void Location( uchar x, uchar y )

{

uchar position;

if( x == 1 )

x = 0x80;

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);

}

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

//* 名称: Clear_Screen()

//* 功能: 清屏

//* 输入: 无

//* 输出: 无

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

void Clear_Screen(void)

{

Write_Cmd(0x34); //扩充指令

Delay_ms(11); //10ms

Write_Cmd(0x30); //基本指令

Delay_ms(1);

Write_Cmd(0x01);//清屏

Delay_ms(10);

}

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

//* 名称: Write_str()

//* 功能: 向12864里写字符串

//* 输入: *p -- 字符串地址

//* 输出: 无

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

void Write_str( uchar *p )

{

while( *p != '\0' )

{

Write_Date(*p);

p++;

}

}

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

//* 名称:Printf_Decimal()

//* 功能:打印浮点类型数据

//* 输入:double Num --要打印的数据

//* 输出:无

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

void Printf_Decimal(double Num)

{

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);

Write_str(s);

SendData(s[0]);

SendData(s[1]);

SendData(s[2]);

SendData(s[3]);

SendData(s[4]);

SendData(s[5]);

SendData('\t');

}

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

// STC12C5

A60S2 PCA/PWM模块 //

//

// 说明: STC12C5A60S2单片机有两路可编程计数器阵列(PCA)模块,可用于软件

// 定时器,外部脉冲的捕捉、高速输出以及脉宽调制(PWM)输出 //

// 涉及寄存器:CMOD(PCA工作模式寄存器) CCON(PCA控制寄存器)

// CCAPM0,CCAPM1(PCA比较/捕获寄存器)

// CH,CL(PCA的16位计数器)、CCAPnL,CCAPnH(PCA捕捉/比较

寄存器)

// PCA_PWM0,PCA_PWM1(PCA模块PWM寄存器)

// AUXR1(辅助寄存器1)

// //

// 程序说明: 本程序实现对PCA/PWM模块的四种工作模式的测试。

//

// 注意:当选择相应的模式时,需在主函数内和中断服务内更改相应模式的初始

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



// 和相应的中断服务程序。去掉注释就可以,若要更改相应模式的功能,需在

相应

// 的初始化函数里更改相应的参数,脉宽调制(PWM)默认设置为无中断

方式

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

/

#include

#include

#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 T5ms (0.005*FOSC) //定时计数值=T/(1/PCA的时钟源)

/*******PWM模式变量更改**********/

#define DR_50 0x7f //50%占空比

#define DR_10 0x19 //10%占空比

/*******时钟源选择*******/

#define CLK_0 0x00 //Sysclk/12

#define CLK_1 0x02 //Sysclk/2

#define CLK_2 0x04 //定时器0的溢出脉冲

#define CLK_3 0x06 //ECI/P1.2(P4.1)输入的外部时钟

#define CLK_4 0x08 //Sysclk

#define CLK_5 0x0a //Sysclk/4

#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位捕获,上升触发中断模式

#define CD_model 0x51 //16位捕获,下降触发中断模式

#define CUD_model 0x71 //16位捕获,跳变触发中断模式

uint value = T100KHz; //100kHz时的CCAP0L值

uint time = T5ms; //5ms时的CCAP0L和CCAP0H值

uint test = 0; //测试用,要删除

sbit LED = P1^7; //用来观测定时模式和捕获模式的现象

//定时模式时500MS闪烁,捕获模式时捕获一次时取反

/*****函数声明*****/

void HP_init(void); //高速模式初始化

void PP_init(void); //PWM模式初始化

void TP_init(void); //定时器模式初始化

void CD_init(void); //捕

获模式初始化

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

// H_model初始化 //

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

void HP_init(void)

{

CMOD = CLK_4; //PCA时钟源为Sysclk

CCAPM0 = H_model; //高速输出模式

CCAP0L = value;

CCAP0H = value>>8;

value += T100KHz;

CR = 1; //开启PCA计数器

EA = 1; //开总中断

}

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

// P_model初始化 //

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

void PP_init(void)

{

CMOD = CLK_4; //时钟源为Sysclk

CCAPM0 = P_model; //无中断PWM模式

CCAP0L = DR_50; //%50占空比

CCAP0H = DR_50; //当CL值大于CCAP0L时输出为高,反之输出为低

//当CL溢出时CCAP0H的值装载到CCAP0L中

CR = 1; //开启PCA计数器

//当不使用定时0溢出为时钟源时,PWM输出的频率=PCA的时钟

源/256

//使用定时器溢出的时钟源时,可设定定时器的值对输出频率的改



//分频为0-256分频

}

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

// T_model初始化 //

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

void TP_init(void)

{

CMOD = CLK_4; //时钟源为Sysclk

CCAPM0 = T_model; //定时模式

CCAP0L = time; //

CCAP0H = time>>8; //定时5ms

time += T5ms;

CR = 1;

EA = 1;

}

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

// CD_model初始化 //

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

void CD_init(void)

{

CMOD = CLK_4;

CCAPM0 = CD_model;

CR = 1;

EA = 1;

}

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

// 主程序 //

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

void main()

{

CD_init();

//PP_init();

//HP_init();

//TP_init();

while(1)

{

}

}

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

// 中断服务 //

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

void CD_Service(void) interrupt 7

{

CCF0 = 0;

LED = ~LED;

}

/*void TP_Service(void) interrupt 7

{

CCF0 = 0; //清除PCA计数器溢出中断标志

test++;

if( test == 100 )

{

test = 0;

LED = ~LED;

}

CCAP0L = time;

CCAP0H = time>>8;

time += T5ms;

} */

/*

void HP_Service(void) interrupt 7

{

CCF0 = 0; //清除PCA计数器溢出中断标志

CCAP0L = value;

CCAP0H = value>>8;

value += T100KHz;

} */

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

// STC12C5A60S2串行通信模块 //

//

// 说明: STC12C5A60S2单片机有2个采用UART工作方式的全双工串行通信接



// 两个串口都有4种工作方式,两种波特率可变,两种波特率固定的

// 串口1为 TxD-P3.1引脚 RxD-P3.0引脚

// 串口2为 当在P1口时 TxD2-P1.3引脚 RxD2-P1.2引脚

// 当在P4口时 TxD2-P4.3引脚 RxD2-P4.2引脚

//

// 涉及寄存器:BRT(独立波特率发生器) AUXR(辅助寄存器)SCON(串行控制寄存器)

// SBUF(数据缓冲寄存器)PCON(电源控制寄存器)IE(中断控制寄存器)

// IP(中断优先级寄存器)IPH()SADEN()SADDR(

)WAKE_CLKO(时钟

唤醒寄存器)

// Bit1 - PD 控制单片机进入掉电模式

// //

// 程序说明: 程序实现从PC端发送数据到单片机,单片机将接收到的数据通过

12864

// 显示出来

//

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

#include

#include

#include "LCD.h"

#define uchar unsigned char

#define uint unsigned int

#define BTL 9600 //若要更改波特率直接更改此处,当波特率大于9600时需修改相应的接收程序,

//可选波特率有以下: 否则有可能出现乱码

//波特率为2400 //波特率为28800

//波特率为4800 //波特率为38400

//波特率为9600 //波特率为57600

//波特率为14400 //波特率为115200

//波特率为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 );

void Receive(void);

void Printf( uchar *p );

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

// 串口初始化 //

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

void UART_init(void)

{

SM0 = 0; //选择串口为方式1工作

SM1 = 1; //8位数据波特率可变

REN = 1;

#if( BTL == 2400 )

BRT = 0x70;

#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;

#elif( BTL == 38400 )

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

BRT = 0xF7;

#elif( BTL == 57600 )

BRT = 0xFA;

#elif( BTL == 115200 )

BRT = 0xFD;

#endif

AUXR = 0x15; //选择独立波特率发生器为串行

//口的波特率发生器,模式为1T

ES = 1; //允许串口中断

IPH = 0X10; //PSH = 1;

IP = 0X10; //PS = 1;串口1中断为最高优先级中断

EA = 1; //开总中断

}

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

// 发送一个字节数据 //

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

void Send_byte( uchar byte )

{

SBUF = byte;

while(!TI);

TI = 0;

}

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

// 打印字符 //

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

void Printf( uchar *p )

{

while( *p != '\0' )

{

Send_byte(*p);

p++;

}

}

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

// 接收函数 //

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

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 )

{

Re = 0;

Clear_Screen();

Location(1,0);

}

Receive_Bflag = 1;

}

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

// 主函数 //

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

*****//

void main()

{

Init_LCD();

UART_init();

while(1)

{

if( RI == 1 )

{

RI = 0;

Receive();

Printf("Success!");

}

if( TI == 1 )

{

TI = 0;

}

}

}

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

// 串口中断服务 //

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

void Com_Service(void) interrupt 4

{

EA = 0;

EA = 1;

}

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

// STC12C5A60S2 SPI接口模块

//

//

// 说明: STC12C5A60S2单片机提供一种高速串行通信接口SPI接口,SPI是一种全

// 双工.高速.同步的通信总线,有两种操作模式:主模式和从模式。

//

// 涉及寄存器:SPCTL(SPI控制寄存器)、SPSTAT(SPI状态寄存器)、SPDAT(数据寄

存器)

// AUXR1(辅助寄存器)

// //

// 程序说明: 本程序为SPI的主机程序,主机通过从串口接收数据并将数据通过SPI

// 传输给SPI的从机。 //****************************************************************************//

#include

#include

#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 CPOL 0x08 //SPICLK空闲时为高电平

#define CPHA 0x04 //数据在SPICLK的前时钟沿驱动,并在后时钟沿采样

#define SP_CLK0 0x00 //SPI时钟频率为CPU_CLK/4

#define SP_CLK1 0x01 //SPI时钟频率为CPU_CLK/16

#define SP_CLK2 0x02 //SPI时钟频率为CPU_CLK/64

#define SP_CLK3 0x03 //SPI时钟频率为CPU_CLK/128

/************对SPSTAT寄存器的设置位宏定义************/

#define SPIF 0x80 //传输完成标志

#define WCOL 0x40 //SPI写冲突标志

/************SPI口切换宏定义***************/

#define SPI_P4 0x20 //SPI从P1口切换到P4口

sbit SPISS = P0^0; //用来选择从机

/************串口波特率设定*************************/

#define BTL 9600 //若要更改波特率直接更改此处,当波特率大于9600时需修改相应的

接收程序,

//可选波特率有以下: 否则有可能出现乱码

//波特率为2400 //波特率为28800

//波特率为4800 //波特率为38400

//波特率为9600 //波特率为57600

//波特率为14400 //波特率为115200

//波特率为19200

void UART_init(void);

uchar Receive(void);

void Printf( uchar *p );

void Init_SPI(void);

void Send_byte( uchar byte );

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

// 串口初始化 // //****************************************//

void UART_init(void)

{

// SM0 = 0; //选择串口为方式1工作

// SM1 = 1; //8位数据波特率可变

// REN = 1; //允许串口接收

SCON = 0x50;

#if( BTL == 2400 )

BRT = 0

x70; //波特率设置为9600

#elif( BTL == 4800 )

BRT = 0xB8;

#elif( BTL == 9600 )

BRT = 0xDC;

#elif( BTL == 14400 )

BRT = 0xE8;

#elif( BTL == 19200 )

BRT = 0xEE;

#elif( BTL == 28800 )

BRT = 0xF4;

#elif( BTL == 38400 )

BRT = 0xF7;

#elif( BTL == 57600 )

BRT = 0xFA;

#elif( BTL == 115200 )

BRT = 0xFD;

#endif

AUXR = 0x15; //选择独立波特率发生器为串行

//口的波特率发生器,模式为1T

// ES = 1; //允许串口中断

// IPH = 0X10; //PSH = 1;

// IP = 0X10; //PS = 1;串口1中断为最高优先级中断

// EA = 1; //开总中断

}

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

// 发送一个字节数据 //

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

void Send_byte( uchar byte )

{

SBUF = byte;

while(!TI);

TI = 0;

}

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

// 打印字符 // //************************************************// void Printf( uchar *p )

{

while( *p != '\0' )

{

Send_byte(*p);

p++;

}

}

//************************************************// // 接收函数 // //************************************************// uchar Receive( void )

{

uchar byte;

_nop_();

_nop_();

_nop_();

_nop_();

if( RI == 1 )

{

RI = 0;

byte = SBUF;

}

return byte;

}

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

//* 名称:Init_SPI()

//* 功能: 对SPI进行初始化

//* 输入:无

//* 输出:无

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

void Init_SPI(void)

{

SPDAT = 0; //清空数据寄存器

SPSTAT = SPIF|WCOL; //清空SPI状态寄存器

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

SPCTL = SPEN|MSTR; //SPI设置为主机模式

IE2 = 0x02; //允许SPI中断

}

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

//* 名称:main

//* 功能:

//* 输入:无

//* 输出:无

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

void main()

{

uchar flag = 0;

UART_init();

Init_SPI();

EA = 1; //开总中断

while(1)

{

flag = Receive();

if(flag) //当PC端有发送数据时才进行SPI传输数据

{

SPISS = 0;

SPDAT = flag;

flag = 0;

}

}

}

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

//* 名称:SPI_ISR()

//* 功能: SPI中断服务

//* 输入:无

//* 输出:无

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

void SPI_ISR(void) interrupt 9 using 1 //使用工作寄存器组1

{

SPSTAT = SPIF|WCOL; //清标志

Printf("Send_Data:");

Send_byte(SPDAT); //从从机中把主机上一次发送的值读回来

Send_byte('\t');

SPISS = 1;

}

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

// STC12C5A60S2 SPI接口模块 //

//

// 说明: STC12C5A60S2单片机提供一种高速串行通信接口SPI接口,SPI是一种全

// 双工.高速.同步的通信总线,有两种操作模式:主模式和从模式。

//

// 涉及寄存器:SPCTL(SPI控制寄存器)、SPSTAT(SPI状态寄存器)、SPDAT(数据寄

存器)

// AUXR1(辅助寄存器)

// //

// 程序说明: 本程序为SPI的从机程序,从机通过SPI接收主机发送过来的数据,并通

过串口

// 显示到PC端,

//

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

#include

#include

#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 CPOL 0x08 //SPICLK空闲时为高电平

#define CPHA 0x04 //数据在SPICLK的前时钟沿驱动,并在后时钟沿采样

#define SP_CLK0 0x00 //SPI时钟频率为CPU_CLK/4

#define SP_CLK1 0x01 //SPI时钟频率为CPU_CLK/16

#define SP_CLK2 0x02 //SPI时钟频率为CPU_CLK/64

#define SP_CLK3 0x03 //SPI时钟频率为CPU_CLK/128

/************对SPSTAT寄存器的设置位宏定义************/

#define SPIF 0x80 //传输完成标志

#define WCOL 0x40 //SPI写冲突标志

/************SPI口切换宏定义***************/

#define SPI_P4 0x20 //SPI从P1口切换到P4口

/************波特率选择********************/

#define BTL 9600 //若要更改波特率直接更改此处,当波特率大于9600时需修改相应的接

收程序,

//可选波特率有以下: 否则有可能出现乱码

//波特率为2400 //波特率为28800

//波特率为4800 //波特率为38400

//波特率为9600 //波特率为57600

//波特率为14400 //波特率为115200

//波特率为19200

void UART_init(void);

uchar Receive(void);

void Printf( uchar *p );

void Init_SPI(void);

void Send_byte( uchar byte );

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

// 串口初始化 // //****************************************//

void UART_init(void)

{

// SM0 = 0; //选择串口为方式1工作

// SM1 = 1; //8位数据波特率可变

// REN = 1; //允许串口接收

SCON = 0x50;

#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;

#elif( BTL == 28800 )

BRT = 0xF4;

#elif( BTL == 38400 )

BRT = 0xF7;

#elif( BTL == 57600 )

BRT = 0xFA;

#elif( BTL == 115200 )

BRT = 0xFD;

#endif

AUXR = 0x15; //选择独立波特率发生器为串行

//口的波特率发生器,模式为1T

// ES = 1; //允许串口中断

// IPH = 0X10; //PSH = 1;

// IP = 0X10; //PS = 1;串口1中断为最高优先级中断

// EA = 1; //开总中断

}

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

// 发送一个字节数据 //

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


void Send_byte( uchar byte )

{

SBUF = byte;

while(!TI);

TI = 0;

}

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

// 打印字符 //

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

void Printf( uchar *p )

{

while( *p != '\0' )

{

Send_byte(*p);

p++;

}

}

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

// 接收函数 //

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

uchar Receive( void )

{

uchar byte;

_nop_();

_nop_();

_nop_();

_nop_();

if( RI == 1 )

{

RI = 0;

byte = SBUF;

}

return byte;

}

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

//* 名称:Init_SPI()

//* 功能: 对SPI进行初始化

//* 输入:无

//* 输出:无

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

void Init_SPI(void)

{

SPDAT = 0; //清空数据寄存器

SPSTAT = SPIF|WCOL; //清空SPI状态寄存器

SPCTL =SPEN; //SPI设置为从机模式

IE2 = 0x02; //允许SPI中断

}

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

//* 名称:main

//* 功能:

//* 输入:无

//* 输出:无

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

void main()

{

uchar flag = 0;

UART_init();

Init_SPI();

EA = 1; //开总中断

while(1)

{

flag = Receive();

if(flag) //当PC端有给从机发送数据时把从机当前的SPDAT值发送出来

{

Send_byte(SPDAT);

flag = 0;

}

}

}

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

//* 名称:SPI_ISR()

//* 功能: SPI中断服务

//* 输入:无

//* 输出:无

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

void SPI_ISR(void) interrupt 9 using 1 //使用工作寄存器组1

{

SPSTAT = SPIF|WCOL; //清标志

Printf("Receive_Data:");

P2 = P2+1; //LED灯表示接收的次数

Send_byte(SPDAT); //读出主机发送过来的数据

SPDAT = SPDAT; //把上一次接收到的值传回主机

Send_byte('\t');

}

相关主题
文本预览
相关文档 最新文档