本文转载,原文地址:http://www.eefocus.com/kinbing/blog/12-01/237787_f0cbf.html
一开始没想用内部时钟243K的.因为说不精确,串口调试会有麻烦.但后来发现外部晶振,用手一摸就停震,而且s08aw系统,看门狗不能用内部1k的时钟,只能用系统时钟.那如果外部晶振,停振.连看门狗都起不了作用.整个死掉.所以就打算用内部的,调校一下精度.
看了手册关于校正内部243K时钟的方法.还是不明白.不知道怎么输入外部时钟信号.后来就打算用1K的内部时钟做一个实时中断.在一个延时函数里开启.当中断时,把延时函数里的数值用液晶显示出来,然后根据这个数值来计算或调整.终于搞定了能用串口通信了.
1.先用外部准确晶振8M.PLL调成16M.得出数值为延时函数的值为2806.
2.用内部时钟按243K调到16M左右.再用ICGTRM 去校正.直到接近2806为止.
/* 硬件SPI与NOKIA 5110液晶 */
/*******头文件*********/
#include hidef.h /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "lcd.h" /* include peripheral declarations */
/***************************脚位***************************/
//还有三个位分别是SPI的 MOSI CLK SSI
word ADC_DATA,ad,ad0_max,ad1_max,ad2_max,ad3_max;
byte a=0;
word a_data;
byte receive_data[10]; //接收数据用的变量
byte receive_data_point;//数据用的指针
word abcd;
void delay(long);
void SPI_Init(void);
void SCI_Init(void);
void send_char(byte);
void send_string(byte * );
void receive(void);
void Vrti1abc(void);
/***************************主函数*******************************/
void main(void)
{
SOPT_COPE=0;//关看门狗
// ICGC1 = 0x78;ICGC2 = 0x01;//外部晶振8M,*4/2 =16M
ICGC1 = 0x28;
ICGC2 = 0x20;
ICGTRM=162;
SPI_Init();
SCI_Init();
PTEDD=0xff;
LCD_init();
LCD_clear();
EnableInterrupts;
for(;;)
{
delay(60000);
}
/* please make sure that you never leave main */
}
/***************************延时函数*******************************/
void delay(word x)
{
SRTISC=0x11;//开始实时中断
for(abcd=0;abcd<x;abcd++)
{
}
}
/***************************SPI初始化*******************************/
void SPI_Init(void)
{
SPI1C1_SPE=1; //SPI使能
SPI1C1_MSTR=1;//SPI为主模式
SPI1C1_CPOL=1;//空闲时钟为高
SPI1C1_SSOE=1; //打开自动 SS
//SPI1C1_SPTIE=1;//打开发送完成中断
SPI1C2_MODFEN=1;//打开自动 SS
SPI1BR=0x00; //16M/8 =2M
}
/************************串口接受中断********************************/
interrupt VectorNumber_Vsci1rx void receive(void)
{
byte r_data;
if(SCI1S1_RDRF) //读SCI1S1_RDRF 接收满标志,再读数据寄存器可以清此标记
{
r_data= SCI1D;
send_char(r_data);
}
}
/************************发送字符串函数********************************/
void send_string(byte * data)
{
while(*(data) != '\0' )//当字符串还没未到结尾符'\0'时发送数据
{
while(!SCI1S1_TDRE); //当发送缓存为空时
SCI1D=*(data);
data++;
}
}
/************************发送字符函数********************************/
void send_char(byte data)
{
while(!SCI1S1_TDRE);//当发送缓存为空时
SCI1D=data;
}
/****************************串口设置------波特率为9600 **************************/
void SCI_Init(void)
{
SCI1BDL=35;//0x68=104 16M/16/9600=104 波特率设置
SCI1C2 =0x2c;
SCI1C2_RIE=1;//打开接收中断
}
/************************实时中断********************************/
interrupt VectorNumber_Vrti void Vrti1abc(void)
{
//把在延时里得到的变量发到液晶显示上查看.
write_6_8_char(abcd/10000+'0',1,2);
write_6_8_char(abcd/1000%10+'0',2,2) ;
write_6_8_char(abcd/100%10+'0',3,2);
write_6_8_char(abcd/10%10+'0',4,2);
write_6_8_char(abcd%10+'0',5,2);
SRTISC=0x00;//关闭实时中断
SRTISC_RTIACK=1; //清标志
}