2015.07.25 STC15单片机学习日记-时钟与复位

来源:互联网 发布:知乎 三国魏 编辑:程序博客网 时间:2024/05/16 11:42

  继续假期写总结的习惯,开始每天总结。百度空间居然倒闭了2015.07.25 <wbr>STC15单片机学习日记-时钟与复位,去年暑假写的VB日记全都没了,怪可惜的。今天看了了STC15单片机的时钟与复位部分。

 STC15出厂时内配有片内RC振荡器时钟,不用再外焊晶振及滤波电容。当有特殊要求时可由XTAL1和XTAL2引脚外接晶振产生时钟信号,也可直接从XTAL1脚输入外部时钟信号,XTAL2脚悬空。

 时钟源输出信号经过一个可编程时钟分频器与CPU、内部接口相连。片内RC振荡器或外接晶振产生的时钟称为主时钟,频率记为fosc。CPU和内部接口的时钟称为系统时钟,频率记为fsys。其关系为fsys=fosc/N。分频系数N可通过特殊功能寄存器CLK_DIV进行选择。其中CLKS2~CLKS0位为分频系统选择位。

  STC15单片机的主时钟fosc可以通过P5.4引脚输出。

 关于复位,分为冷启动和热启动。冷启动复位后上电复位标志位PDF为置1,可软件清0。其在PCON寄存器内。今天才知道单片机的寄存器地址不能被8整除便不可直接操作位,需要用与操作读取。例如上电复位标志位PDF在PCON寄存器中的D4位,即00010000。当读取其值时,用a=PCON&0x10;读取状态。若PDF为1则为系统停电后再上电引起的硬复位,为0则是RST引脚人为使单片机复位、内部看门狗产生复位或操作IAP_CONTR寄存器实现的代码复位。

 STC15单片机在烧录器中可设置低电压检测值。当内部电压VCC低于低压检测门限电压时,PCON寄存器中LVDF将自动置1。可在烧录时选择LVDF置1时单片机复位或是申请中断停止程序。

 今天对上电复位标志位比较感兴趣,还写了一个小测试程序,不管如何变化复位方式他的值都是1。贴上代码明天继续研究。

#include "stc15.h"
#include "096oled.h"
#include "font.h"


sbitOLED_SPI_SDIN=P1^5;    //SPI通信数据线
sbitOLED_SPI_SCLK=P1^6;               //SPI通信时钟线
sbitOLED_SPI_DC=P1^7;     //SPI通信命令数据选择
sbitOLED_SPI_RST=P5^5;                //OLED复位引脚     

int angle,a;  //临时变量;

void OledWriteByte(uchar wbyte,uchar cmd)
{
 uchar i;

 OLED_SPI_DC=cmd;
 for(i=0;i<8;i++)
 {
  OLED_SPI_SCLK=0;
  if(wbyte&0x80)
  {
   OLED_SPI_SDIN=1;
  }
  else
  {
   OLED_SPI_SDIN=0;
  }
  OLED_SPI_SCLK=1;
  wbyte<<=1;
 }
}


void OledInit(void)
{
 
 OledWriteByte(SET_DISPLAY_OFF,OLED_CMD);
 
 
   OledWriteByte(SET_DISPLAY_CLOCK,OLED_CMD);
   OledWriteByte(0x80,OLED_CMD);
  
 
 OledWriteByte(SET_MULTIPLEX_RATIO,OLED_CMD);    //驱动路数设置命令
 OledWriteByte(0x3F,OLED_CMD);        //驱动路数值

 
 OledWriteByte(SET_DISPLAY_OFFSET,OLED_CMD);     //显示偏移设置命令
 OledWriteByte(0x00,OLED_CMD);        //取值范围:0x00-->0x3F

 
 OledWriteByte(0x40,OLED_CMD);        //取值范围:0x40---0x7F
 
 
 OledWriteByte(CHARGE_PUMP_SET,OLED_CMD);     //电荷泵设置命令
 OledWriteByte(0x14,OLED_CMD);        //开启电荷泵

 
 OledWriteByte(SET_MEMORY_ADDR_MODE,OLED_CMD);    //内存地址模式设置命令
 OledWriteByte(0x10,OLED_CMD);        //设置地址模式值:0x00,列地址模式;0x01,行地址模式;
                //0x10,页地址模式;
            
 OledWriteByte(SET_SEGMENT_REMAP_A1,OLED_CMD);    //列地址0映射到SEG127

 
 OledWriteByte(SET_COM_SCAN_DIRECTION_C8,OLED_CMD);   //行地址0映射到COM63
 
           
 OledWriteByte(SET_COM_PINS_CONFIG,OLED_CMD);    //设置COM硬件引脚配置命令
 OledWriteByte(0x12,OLED_CMD);

 
 OledWriteByte(SET_CONTRAST_CONTROL,OLED_CMD);     //对比度设置命令
 OledWriteByte(0x8F,OLED_CMD);         //对比度值,取值范围1-255
 
 
 OledWriteByte(SET_PRECHARGE_PERIOD,OLED_CMD);
 OledWriteByte(0xF1,OLED_CMD);
 
 
 OledWriteByte(SET_VCOMH_DESELECT_L,OLED_CMD);
 OledWriteByte(0x30,OLED_CMD);

 
   OledWriteByte(ENTIRE_DISPLAY_ON_A4,OLED_CMD);

 
 OledWriteByte(NORMAL_DISPLAY,OLED_CMD);     //0:熄灭像素;1:点亮像素

 
 OledWriteByte(SET_DISPLAY_ON,OLED_CMD);
 
 
 OledClearn();
}


void OledClearn(void)
{
 uchar i,j;

 for(i=0;i<8;i++)
 {
  OledWriteByte(0xb0+i,OLED_CMD);    //设置页地址
  OledWriteByte(0x00,OLED_CMD);    //设置列低地址
  OledWriteByte(0x10,OLED_CMD);    //设置列高地址

  for(j=0;j<128;j++)
  {
   OledWriteByte(0x00,OLED_DATA);
  }

 }
}


void DisplayChar_12X06(uchar x,uchar y,uchar *dispdata)
{
 uchar i,j,fontposition,addyl,addyh;
 uchar *databuf;

 while((*dispdata)!=0)
 {
  
  fontposition=*dispdata-0x20;     //计算字符在字库中的位置
  databuf=(uchar*)(ASCII_1206+fontposition);  //获取字符点阵数据起始地址
  
  
  addyl=y;          //计算列低地址
  addyh=y/16+0x10;        //计算列高地址

    
  for(i=0;i<2;i++)
  {
   OledWriteByte(0xb0+x+i,OLED_CMD);   //设置页地址
   OledWriteByte(addyl,OLED_CMD);    //设置列低地址
   OledWriteByte(addyh,OLED_CMD);    //设置列高地址

   for(j=0;j<6;j++)
   {
    OledWriteByte(*(databuf++),OLED_DATA); 
       
  }

  y+=6;           //列地址自加6
  dispdata++;
 
}

void display(unsigned char y,unsigned char x,int a)
 
 uchar a1,a2,a3;      //个位
 if(a<0)
 {
  DisplayChar_12X06(y,x,"-"); 
  a=-a;
 }
 else DisplayChar_12X06(y,x," ");

 a1=a/100;     //百位数
 a2=a0/10;       //十位数
 a3=a; 
 switch(a1)
 {
  case1:DisplayChar_12X06(y,x+6,"1");break;  //1
  case2:DisplayChar_12X06(y,x+6,"2");break;  //2
  case3:DisplayChar_12X06(y,x+6,"3");break;  //3
  case4:DisplayChar_12X06(y,x+6,"4");break;  //4
  case5:DisplayChar_12X06(y,x+6,"5");break;  //5
  case6:DisplayChar_12X06(y,x+6,"6");break;  //6
  case7:DisplayChar_12X06(y,x+6,"7");break;  //7
  case8:DisplayChar_12X06(y,x+6,"8");break;  //8
  case9:DisplayChar_12X06(y,x+6,"9");break;  //9
  default:DisplayChar_12X06(y,x+6,"0");break;   //0
 }
 switch(a2)
 {
  case1:DisplayChar_12X06(y,x+12,"1");break;  //1
  case2:DisplayChar_12X06(y,x+12,"2");break;  //2
  case3:DisplayChar_12X06(y,x+12,"3");break;  //3
  case4:DisplayChar_12X06(y,x+12,"4");break;  //4
  case5:DisplayChar_12X06(y,x+12,"5");break;  //5
  case6:DisplayChar_12X06(y,x+12,"6");break;  //6
  case7:DisplayChar_12X06(y,x+12,"7");break;  //7
  case8:DisplayChar_12X06(y,x+12,"8");break;  //8
  case9:DisplayChar_12X06(y,x+12,"9");break;  //9
  default:DisplayChar_12X06(y,x+12,"0");break;   //0
 }
 switch(a3)
 {
  case1:DisplayChar_12X06(y,x+18,"1");break;  //1
  case2:DisplayChar_12X06(y,x+18,"2");break;  //2
  case3:DisplayChar_12X06(y,x+18,"3");break;  //3
  case4:DisplayChar_12X06(y,x+18,"4");break;  //4
  case5:DisplayChar_12X06(y,x+18,"5");break;  //5
  case6:DisplayChar_12X06(y,x+18,"6");break;  //6
  case7:DisplayChar_12X06(y,x+18,"7");break;  //7
  case8:DisplayChar_12X06(y,x+18,"8");break;  //8
  case9:DisplayChar_12X06(y,x+18,"9");break;  //9
  default:DisplayChar_12X06(y,x+18,"0");break;   //0
 }

}

void main(void)
{
 OledInit(); 
 while(1)
 {
  a=PCON&0X10;

  display(0,0,a);
 }

 

0 0
原创粉丝点击