2015.07.25 STC15微控制器學習日記-時鐘與復位

PeterrrWang發表於2016-07-02

  繼續假期寫總結的習慣,開始每天總結。百度空間居然倒閉了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);
 }

 

相關文章