2014年9月3日 星期三

stm32f030f4p6



stm32f030f4p6 TSSOP20包裝 16KFlash rom 4K ram 零售一個13元 , 買了幾個來試試 ,先銲在轉接板上,首先到官網下載 , STM32F0xx_StdPeriph_Lib_V1.3.1 , 然後 用keil 4.74版(試用版的就可以,因為可以支持到32k,而stm32f030f4p6只有16k) 開啟 檔案 編譯 燒入(我是用網拍的JLink) , 恩 果然可以執行 , 事後 用keil 4.2版 開啟 編譯過不了 , 看來還是 用keil 4.74版好了
專案的路徑 :STM32F0xx_StdPeriph_Lib_V1.3.1\Projects\STM32F0xx_StdPeriph_Templates\MDK-ARM\Project.uvproj

2014年9月2日 星期二

非主流的包裝

昨晚入手2pcs MBI5024 , 早上迫不及待要焊在轉接板上,好好測試一下,要焊的時候才發現它的包裝和別人不一樣 , 啊啊 它卡在 SOP 和 SSOP的中間 ,SOP腳距是1.27mm SSOP 0.65mm 而他老兄是1mm , 看來要為它特別畫個轉接板才能用 

2014年8月25日 星期一

人機介面 和 單晶片

HMI 人機介面 對我而言 , 很陌生完全沒用過 , 因工作 需要用人機介面和單晶片連接 ,一般HMI是連接PLC , 查資料後 知它通訊是走MODBUS RTU , 手上沒 人機介面實體機器 , 還好 HMI 有很好的模擬軟體 , 所以先用 PC 模擬HMI 連接單晶片 , 我是一對一 所以 用 RS232 , 單晶片上外接的LED 對應 HMI 裡的一個按鍵輸出 , 外接的七段顯示器 是 HMI 裡的設定值(條棒), 而 HMI 裡的跳動數字 是 由單晶片產生的 計數值 , 目前這個測試 是把單晶片設 MASTER , HMI 為 SLAVE
  

2014年7月30日 星期三

參加新唐研習會


前些日子去參加新唐的研習會 , 這次 用一套叫 NuEdu 的 教材 照如下, 上完課可以帶回家 ,真是 高大上的禮物,( 高端 大氣 上檔次 )



 連接器出腳 , 和 ARDUINO 相容 
和 ARDUINO 相容的 簡易IO 板
  組在一起的情形
   牛橋 簡易的信號 檢測工具 



2014年7月20日 星期日

Miss MCU 包裝 畫錯

哇哇 MCU 包裝 畫錯, 完全沒辦法使用 . 原因是 LQFP64 腳距有0.4mm (笙泉MG82FE316就是這種包裝 ) 0.5mm (新唐NCU100 其實目前很多元件是這個包裝 ) 而我 PCB 是用NCU100卻畫成0.4mm 腳距, 真是不小心 以後 板子檔案要送出時 , 要列印出來看看 較安全
前方是 錯誤板子 , 後方是修正後的板子 

2014年7月8日 星期二

usb 接口

usb接口,越做越小,當然小在pcb上所佔的空間就越小,不是壞事,現在手機都用
micro usb 應應趨勢 自己的pcb 也漸漸改用micro usb ,估計 micro usb 比 mini usb 節省 1/2 面積


2014年6月12日 星期四

自製電壓電流表

自製一個電壓電流表, 電流解析度是 0.01 A ,電壓解析度是 0.1V  ,負載我接5歐姆電阻 , 數字顯示部分 下方是電流 上方是電壓 , 數字顯示部分 和 直流電源供應器是顯示一致 , 目前ADC是使用 天微 說到這裡 插話一下 , 最早是用 他的TM7709 一下子這型號就停產 , 後來該用 TM7710 最近 也要停了 , 真是很煩  , 所以正式版決定改 HY3102 紘康科技 HYCON 

2014年6月4日 星期三

小車試走


配合上篇 紅外線的讀值 , 做比例控制 , 行走的情形

2014年6月2日 星期一

自走車 紅外線



以前 我都以為自走車的前頭的紅外線是讀有沒有在黑線上, 有 或是 沒有 , 到最近有朋友跟我說 , 我才知道 原來是用adc 讀 黑線的偏移量, 這樣子的話  相較於之前的想法 , 解析度就增加多
實際情形可以看上面影片,證明

2014年5月26日 星期一

推出Arduino Zero


新推的Arduino Zero mcu是用ATSAMD21G18, 48pins LQFP
ARM Cortex-M0+ CPU running at up to 48MH
  • 規格如下

MicrocontrollerATSAMD21G18, 48pins LQFP
Operating Voltage3.3V
Digital I/O Pins14, with 12 PWM and UART 
Analog Input Pins6, 12-bit ADC channels
Analog Output Pins1, 10-bit DAC
DC Current per I/O Pin7 mA
Flash Memory256 KB
SRAM32 KB
EEPROMup to 16KB by emulation
Clock Speed48 MHz
我個人比較有興趣的事,並不是arduino 而是 Atmel 的Cortex系列,能夠因為搭上arduino的順風車,而在市場上 一舉占有市場嗎? 以現今的M0 M3 的價格,已經壓制住傳統8051空間,並且M0 M3也已百家爭鳴,Atmel 推Cortex系列算比較晚, 他能藉由Arduino Zero強佔一片市場嗎?
我們台灣目前有   新唐  M0 M4 , 松翰 M0 , Holtek盛群 M3  是很好的選擇, 尤其是 新唐 在市場上的耕耘是很用力的, 在台灣 各大都市定期都有開免費研習會, 上課資訊在他們的官網友公布 ,可以善加利用 

2014年5月15日 星期四

Power Seminar 台中場


昨天去參加了 Fairchild Power Seminar 台中場


2014年4月28日 星期一

在PCB上,使用QFN

在PCB 使用QFN , 看下圖元件 其器件上並沒有出腳,只在斷面上有一點露銅
手工銲接時,要將元件銲點和PCB對齊是一件難事,因為元件沒腳再加上四面都要對齊,一開始我也這麼認為,看下圖PCB 其PAD 有延伸出去,就把它當作元件的出腳,而PAD邊有四個白色直角,只要將元件BODY的四個角,對準PCB上的那四個角 這樣所有銲點就全部對齊

下圖對齊的樣子 
先用烙鐵 融一坨錫將它固定
再在其他位置上開始銲, 用整坨錫 再用烙鐵將錫在銲點上移動,不用擔心  它自動會分開,因為PCB防銲層的關係,有表面張力會把溶解的錫推開 
\
注意看下圖  有一個點沒銲好, 再重新跑一次 上圖的動作  
四面  都依序銲好的樣子  上有松香焦油

用藥用酒精 洗過 ,並且衛生紙擦過 (酒精可以溶解附著在PCB上的松香焦油)
完成

             


2014年4月24日 星期四

資訊分享 三

Fairchild宣佈2014年度北美洲和亞洲功率技術研討會時間表
  "台灣只有台中一場,機會難的"
本年度研討會主題為“工程能效”,將重點探討如何説明Fairchild客戶解決功率管理方面的難題, 美國加州聖約瑟 – 201449 – Fairchild宣佈第八季全球知名功率技術研討會在北美洲和亞洲的舉辦時間。

研討會由一些頂級的業界電源專家組織安排,旨在讓客戶和經銷商借此機會瞭解最新的技術,以解決他們每日面對的功率管理挑戰。


這些為期一天的綜合研討會將圍繞“工程能效”這一主題展開並提供豐富的技術性和實用性簡報,簡報內容包括最新的先進電源概念、基本設計理念的教程回顧以及親自體驗實際應用示例等,以幫助設計工程師打造出震撼的供電產品。

2014年度功率技術研討會全新主題包括:

    LLC諧振轉換器: 設計問題和解決方案
    驅動高功率工業燈具中的HB-LED
    降壓功率因數校正的電流波形調整策略
    採用快速反覆運算方法提高反激式設計性能
    可在低電壓DC-DC應用中實現最優效率和尺寸的封裝技術的發展


2014年4月21日 星期一

USB LAMP

在網拍看到的,USB燈 大都用電阻限流,且並聯驅動 ,效率不是很好,可能是成本考量吧,下面都是我平時,做來把玩的板子,
第一片是用APE1612昇壓恆流驅動, 第二片是用7135降壓恆流驅動,一般手電筒都用這個方案,第三片是XL6001 昇壓恆流驅動,下圖也是XL6001只是 重畫板子而已

實際點亮效果 
由左開始 暖白 紅 綠 藍 

針對LED的發光角度問題,用雙面都有銲LED來加強 


2014年4月4日 星期五

DIY 5WLED燈泡

不多說,看照片應該就能了解





2014年3月31日 星期一

DIY香水移動電源

                             因測試需要買了10個香水移動電源套件回來自己DIY 如下圖
其實也不算甚麼DIY 就只是把 PCB 放入塑膠盒中,再放入一個18650電池蓋上白色蓋子即完成
不過,因好奇PCB上少了一個元件,經查證缺的那個元件是DW06D 作用是防止電池過度放電的功能,呀呀 ! 少了他會讓電池 壽命變短啊 ,這是甚麼居心 ?

缺DW06D的情形下 ,會放電到2.2V 這18650 鋰電池會被他害死的,需另外再購入DW06D自己來銲,這樣算一算 ,真省不了多少錢

市面上的香水或口紅移動電源,都是中國製的,我買的這個還留下一個陷阱,讓18650壽命變短真是....

2014年3月26日 星期三

資訊分享(2014-3-26)


希望對你有幫助

2014年3月25日 星期二

做了幾片PCB

之前都是用手銲的,終於作了一片專用板

這個USB燈有恆定電流控制,不是用電阻限流,用一個18650電池,可以連續點亮10小時 

火紅的 LM2596S DC2DC 降壓 

2014年3月24日 星期一

LED 混色



我這個是用TM1804 ,市面上的七彩燈條大部分是用WS2801不過都大同小異啦
一般玩七彩燈條會買專用的控制器,我這個只是玩玩所以用MCU 直驅TM1804 ,
這IC 的控制線只有一條 所以時序上要求較緊張,在第一張圖片裡有其時序規格 ,
MCU是用82E54 晶振24Mhz,所以1cycle是0.042uSec 其控制方式,下次再聊 

老MCU

PIC16F72好老的單片機不過比PIC16F5X好一些啦,多了ADC TIMER0 TIMER1 TIMER2中斷等,

       2K x 14字的程序存儲器,
      128×8個字節的數據存儲器(RAM)
       八級深硬件堆棧<< 堆疊只有8層
麻煩的是使用數據存儲要先切到正確的銀行,光看到這規格是不是就打退堂鼓了呢?
因為手上剛好有這芯片就順手測試一下,就當作是筆記下面練習程式啟動計時1中斷,
(這顆的中斷位置是所有中斷一起共用的,所以進到中斷副程式時要先檢查是哪一個中斷裝置發生中斷)令端口_A每進一次中斷就反向輸出一次

列表P = 16F72; 列表指令來定義處理器
#包括         ; 具體的處理器變量定義

__config _CP_OFF​​&_WDT_OFF&_BODEN_OFF&_PWRTE_ON&_XT_OSC

; “__config'指令用於內。asm文件中嵌入的配置數據。
; 下列指令的標籤都位於各自的。增量文件。
; 請參閱相關的數據表上的配置字的更多信息。

; *****變量定義(舉例)

W_TEMP EQU 32H
STATUS_TEMP EQU 31H
FLAG_A EQU 30H

; ****************** *********************
        ORG量0x000; 處理器復位向量
                轉到開始; 進入程序開始


INT_VECTOR:
        ORG量0x004; 中斷向量地址
MOVWF W_TEMP; 節省了電流W寄存器的內容;
MOVF 狀態,W; 移動狀態寄存器為W寄存器
BCF STATUS,RP0; 確保文件寄存器組設置為0
MOVWF STATUS_TEMP; 節省OFF狀態寄存器的內容


; ISR代碼可以去這裡或位於其他位置的子程序調用
               BANKSEL PIR1; TMR1IF
               BTFSS PIR1,0
               GOTO VECTOR_QUIT
               BCF PIR1,0; CLR TMR1IF
               COMF FLAG_A,0;取FLAG_A的補數
               MOVWF FLAG_A
               MOVLW B'11110000'; RELOAD TMR1H TMR1L
               MOVWF TMR1L
               MOVLW B'00000000'
               MOVWF TMR1H

VECTOR_QUIT:
      BCF STATUS,RP0; 確保文件寄存器組設置為0
      MOVF STATUS_TEMP,W; 找回狀態寄存器副本
      MOVWF 狀態; 恢復預ISR狀態寄存器的內容
      SWAPF W_TEMP,F
      SWAPF W_TEMP,W; 恢復預ISR W寄存器的內容
      RETFIE; 從中斷返回
開始:
        BANKSEL ADCON1; 16F72復位>> PORTA均設定為ADC
        MOVLW B'00000111'; PORTA至數字IO
        MOVWF ADCON1
        BANKSEL TRISA
        MOVLW B'00000000'
        MOVWF TRISA
        MOVWF TRISB
        MOVWF TRISC
        BANKSEL PORTA

        MOVLW 80H
        MOVWF PORTC
        MOVLW 0
        MOVWF 33H

    ; T1CON = 0B00110101;
        BANKSEL T1CON
        MOVLW B'00110101'
        MOVWF T1CON

 
    ; TIMER1為16BIT上數計數器
        MOVLW B'11110000'
        MOVWF TMR1L; 0X00F0
        MOVLW B'00000000'
        MOVWF TMR1H

   ; TMR1IE = 1; / /外設中斷使能
        BANKSEL PIE1
        MOVLW B'00000001'
        MOVWF PIE1

    ; PEIE = 1 ;/ /使能計時器1中斷
    ; GIE =​​ 1; / /全域中斷使能
        BANKSEL INTCON
        MOVLW B'11000000';
        MOVWF INTCON

LOOP:

         BTFSC FLAG_A,0
         GOTO OFF_LED
         MOVLW B'00000000';
         MOVWF PORTA
         GOTO LOOP
OFF_LED:
         MOVLW B'11111111';
         MOVWF PORTA
         GOTO LOOP

         完

2014年3月11日 星期二

趨勢

很久以前曾購買"時鐘4位led",找東西時不小心浮上桌面,隨手銲一片洞洞板,線路如上圖,然後分別在89E58,Atmega16,Nuc100執行一樣功能的程序
笙泉89E58

atmel的Atmega16


新唐NUC100
由下面3支程序可看出,C 在跨平台上,真的很方便 主程式並沒有做甚麼改變,不同處只有各自的TIMER設定,GPIO設定及位(BIT)操作,我一直以來都是用8X51組合語言在寫程序,偶而用PIC16F5X組合語言,自從接觸到 LPC2103(ARM7)後,強烈感覺用C真的比組合語言輕鬆很多,深刻感覺大勢所趨 呵呵 ,另外 一個趨勢"ARDUINO"這個板子,對初學者應該很便利,個人感到快被"ARDUINO"淹沒, Atmel Atmega系列因"ARDUINO"而得以熱銷,對Atmel 是件好事, 但感覺好像有點怪怪的,你有感覺到嗎?
//89e58程序 IDE  KEIL C
//  Function:時鐘計時
//  基板:      
#include "REG_MPC89L51-515.H"
#include "INTRINS.H"
  // io port Description
#define _ONE    P10  //個
#define _TWO    P11  //拾
#define _THREE  P12  //百
#define _FOUR   P13  //千
#define KEY     P42

const _7_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0xff }; 
unsigned char time_cnt,min_cnt=43,hour_cnt=12,show_time=0;
unsigned char _1_sec_cnt=0x28 ; //一秒 計時
unsigned char  scan_cnt=0X00;   //顯示掃瞄的位數指標
unsigned char disp_0,disp_1,disp_2,disp_3;
bit  _05sec,hour_sw=0;

//-------------------------------------------------
void Init_IRQ()
{

    ET1     =   0x01; //Enable Timer Interrupt 1
    TMOD    =  0X10 ;
    TH1     =  0X3C ;          
    TL1     =  0XB0 ; 
    EA      =  0x01 ; //Enable All Interrupt                    
    TR1     =  0X01 ; //START TIMER1
  
}

void Timer_Interrupt_1() interrupt 3
{
    _1_sec_cnt -- ;
   if (_1_sec_cnt==0)       // 計算 1秒
    {  time_cnt ++ ;
       _1_sec_cnt=0x28 ;
    }
     
   if(_1_sec_cnt>=0x14)     // 產生0.5 Sec
        {_05sec=1;}
   else {_05sec=0;}

   if (time_cnt>=60)    //每60秒進一
    { min_cnt+=1;
          time_cnt=0; 
         } 
   if (min_cnt>=60)    //每60分進一
    { hour_cnt+=1;
          min_cnt=0; 
         } 

     TH1    =  0X3C ;          
     TL1    =  0XB0 ; 
}

main()
{
    Init_IRQ();
//-----------------------------------------------
while (1)
{
     if (scan_cnt>3) scan_cnt=0x00;


     switch(scan_cnt)
       {case 0:
                    P2=0XFF;
                    _ONE=0x00;
                    _TWO=0x01;
                    _THREE=0X01;
                    _FOUR=0X01;
                    if (05sec==1) {P2= _7_seg[disp_0]&0x7f;}
                     else {P2= _7_seg[disp_0]|0x80;}
                //    P2= _7_seg[disp_0] ;
               scan_cnt ++ ;
                    break;

        case 1:
                     P2=0XFF;
                    _ONE=0x01;
                    _TWO=0x00;
                    _THREE=0X01;
                    _FOUR=0X01;
                    if (05sec==1) {P2= _7_seg[disp_1]&0x7f;}
                     else {P2= _7_seg[disp_1]|0x80;}
                 //   P2= _7_seg[disp_1] ;
                    scan_cnt ++ ;
                    break;
                    
        case 2:
                    P2=0XFF;
                    _ONE=0x01;
                    _TWO=0x01;
                    _THREE=0X00;
                    _FOUR=0X01;

                    P2= _7_seg[disp_2] ; 
                    scan_cnt ++ ;
                    break;
        case 3:
                    P2=0XFF;
                    _ONE=0x01;
                    _TWO=0x01;
                    _THREE=0X01;
                    _FOUR=0X00;

                    P2= _7_seg[disp_3] ;  
                    scan_cnt ++ ;
                    break;
        } 
                    disp_0 = time_cnt % 10 ;  
                    disp_1 = (time_cnt/10)%10 ;  
    
                    disp_2= (min_cnt%10); 
                    disp_3 = (min_cnt/10)%10 ; 
                           
         }
  
}
//----------------------------------------------------------------------------------------
//Atmega16  IDE AVR studio4.18
#include "avr/interrupt.h"
#include "avr/iom16.h"
#include "avr/io.h"

const unsigned char _7_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0xff };
unsigned char time_cnt,min_cnt=43,hour_cnt=12,show_time=0;
unsigned char _1_sec_cnt=0x28 ; //一秒 計時
unsigned char  scan_cnt=0X00;   //顯示掃瞄的位數指標
unsigned char disp_0,disp_1,disp_2,disp_3;
//USER_FLAG_a------------------
unsigned char  flag_a=0x00;
unsigned char  _05sec=1;

#define _ONE_OFF     PORTB|=_BV(4)    //個
#define _ONE_ON      PORTB&=~_BV(4)
#define _TWO_OFF     PORTB|=_BV(3)    //拾
#define _TWO_ON      PORTB&=~_BV(3)
#define _THREE_OFF   PORTB|=_BV(2)    //百
#define _THREE_ON    PORTB&=~_BV(2)
#define _FOUR_OFF    PORTB|=_BV(1)    //千
#define _FOUR_ON     PORTB&=~_BV(1)

ISR (TIMER0_OVF_vect)
{
 TCNT0 = 0x3D; //reload counter value
   _1_sec_cnt -- ;

   if (_1_sec_cnt==0)       // 計算 1秒
    {  time_cnt ++ ;
       _1_sec_cnt=0x28 ;
    }
   if(_1_sec_cnt>=0x14)     // 產生0.5 Sec
          { flag_a|=_BV(_05sec);}
   else
         {flag_a&=~_BV(_05sec);}

    if (time_cnt>=60)    //每60秒進一
    { min_cnt+=1;
          time_cnt=0;
         }
   if (min_cnt>=60)    //每60分進一
    { hour_cnt+=1;
          min_cnt=0;
         }
}

void timer0_init(void)
{
      TCCR0 = 0x00;  //stop
      TCNT0 = 0x3D;  //set count
      OCR0  = 0xC3;  //set compare
      TCCR0 = 0x05;  //start timer
}

int main(void)
{
        DDRA=0Xff;
        PORTA=0Xff;

        DDRB=0Xff;
        PORTB=0Xff;
       //stop errant interrupts until set up
        cli(); //disable all interrupts

        timer0_init();

        MCUCR = 0x00;
        GICR  = 0x00;
        TIMSK = 0x01;  //timer interrupt sources
        sei();         //re-enable interrupts
 //all peripherals are now initialized

while (1)
{
     if (scan_cnt>3) scan_cnt=0x00;

     switch(scan_cnt)
       {case 0:
                   PORTA=0XFF;
                    _ONE_ON;
                    _TWO_OFF;
                    _THREE_OFF;
                    _FOUR_OFF;

                    if (bit_is_set(flag_a,_05sec)) {PORTA= _7_seg[disp_0]&0x7f;}
                     else {PORTA= _7_seg[disp_0]|0x80;}

                  //  PORTA= _7_seg[disp_0] ;
               scan_cnt ++ ;
                    break;

        case 1:
                    PORTA=0XFF;
                    _ONE_OFF;
                    _TWO_ON;
                    _THREE_OFF;
                    _FOUR_OFF;

                    if (bit_is_set(flag_a,_05sec)) {PORTA= _7_seg[disp_1]&0x7f;}
                     else {PORTA= _7_seg[disp_1]|0x80;}
                 //   led_segment= _7_seg[disp_1] ;
                    scan_cnt ++ ;
                    break;
                 
        case 2:
                    PORTA=0XFF;
                    _ONE_OFF;
                    _TWO_OFF;
                    _THREE_ON;
                    _FOUR_OFF;

                   PORTA= _7_seg[disp_2] ;

                    scan_cnt ++ ;
                    break;
        case 3:
                    PORTA=0XFF;
                    _ONE_OFF;
                    _TWO_OFF;
                    _THREE_OFF;
                    _FOUR_ON;

                    PORTA= _7_seg[disp_3] ;
                    scan_cnt ++ ;
                    break;
        }
                    disp_0 = time_cnt % 10 ;
                    disp_1 = (time_cnt/10)%10 ;
                    disp_2= (min_cnt%10);
                    disp_3 = (min_cnt/10)%10 ;

}
}
//-------------------------------------------------------------------------------
//新唐 Cortex M0  NUC100  IDE MDK KEIL 4.2
#include
#include "NUC1xx.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvSYS.h"

#define led_segment GPB_DOUT
#define _ONE    GPIOA->DOUT.DOUT4   //個
#define _TWO    GPIOA->DOUT.DOUT5   //拾
#define _THREE  GPIOA->DOUT.DOUT6   //百
#define _FOUR   GPIOA->DOUT.DOUT7   //千   
          
#define  BIBI     DOUT8
#define ON_BIBI  GPIOB->DOUT.BIBI=0
#define OFF_BIBI GPIOB->DOUT.BIBI=1
#define  KEY0     PIN15
const char _7_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0xff }; 
unsigned char time_cnt,min_cnt=43,hour_cnt=12,show_time=0;
unsigned char _1_sec_cnt=0x28 ; //一秒 計時
unsigned char  scan_cnt=0X00;   //顯示掃瞄的位數指標
unsigned char disp_0,disp_1,disp_2,disp_3;

typedef struct
{
         
        struct 
        {
            __IO uint32_t  bibi_1:1;
            
            __IO uint32_t  _05sec:1;            
            __IO uint32_t  hour_sw:1;            
            __I  uint32_t  RESERVE:29;
        } Config;
   
} UART_FLAG_T;
UART_FLAG_T User1;

// User1.Config.hit_one = 1;
signed char dump_num=0,bi_time=5;
unsigned char cnt0=0,cnt1=0,cnt2=0,auto_hit=0;
unsigned char cnt02=0,cnt12=0,cnt22=0,auto_hit2=0;
volatile uint32_t FLAG_0=0;

void TMR0_IRQHandler(void) // Timer0 interrupt subroutine 
  TIMER0->TISR.TIF =1;
////////////////////////////////////////
   if (User1.Config.bibi_1==1)
       { bi_time--;
         if(bi_time<=0)
           {User1.Config.bibi_1=0;
            bi_time=5;
            OFF_BIBI ;
           }
         else
           {ON_BIBI; } 
}

    _1_sec_cnt -- ;
   if (_1_sec_cnt==0)       // 計算 1秒
    {  time_cnt ++ ;
       _1_sec_cnt=0x28 ;
    }
     
   if(_1_sec_cnt>=0x14)     // 產生0.5 Sec
        {User1.Config._05sec=1;}
   else {User1.Config._05sec=0;}

   if (time_cnt>=60)    //每60秒進一
    { min_cnt+=1;
          time_cnt=0; 
         } 
   if (min_cnt>=60)    //每60分進一
    { hour_cnt+=1;
          min_cnt=0; 
         } 
 // TIMER0->TISR.TIF =1;
}
//
void Timer_initial(void)
{
/* Step 1. Enable and Select Timer clock source */ 
     /* 切換IP模組的時鐘源 */   
SYSCLK->CLKSEL1.TMR0_S = 0; //Select 12Mhz for Timer0 clock source 
        SYSCLK->APBCLK.TMR0_EN =1; //Enable Timer0 clock source

/* Step 2. Select Operation mode */
TIMER0->TCSR.MODE=1; //Select periodic mode for operation mode

/* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
TIMER0->TCSR.PRESCALE=0;   // Set Prescale [0~255]
TIMER0->TCMPR  = 300000  ; // Set TICR(TCMP) [0~16777215]
          // (1/12000000)*(0+1)*(300000)= 250usec 
/* Step 4. Enable interrupt */
TIMER0->TCSR.IE = 1;
TIMER0->TISR.TIF = 1; //Write 1 to clear for safty
NVIC_EnableIRQ(TMR0_IRQn); //Enable Timer0 Interrupt

/* Step 5. Enable Timer module */
TIMER0->TCSR.CRST = 1; //Reset up counter
TIMER0->TCSR.CEN = 1; //Enable Timer0

  TIMER0->TCSR.TDR_EN=1; // 
}

/*-----------*/
/*  Main Function  */
/*-----------*/
int main(void)
{
//volatile int32_t i32delay=1000;
/* SYSCLK =>12Mhz*/
UNLOCKREG();

  
    SYSCLK->PWRCON.XTL12M_EN = 1 ;

  while(SYSCLK->CLKSTATUS.XTL12M_STB==0);

SYSCLK->CLKSEL0.HCLK_S=0;
SYSCLK->CLKSEL0.STCLK_S=0;
//------------------------------------
    GPIOA-> PMD.PMD4 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOA-> PMD.PMD5 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOA-> PMD.PMD6 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOA-> PMD.PMD7 = 0X03;   // 設為雙向,和51_IO 相同
    
    GPIOB-> PMD.PMD0 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOB-> PMD.PMD1 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOB-> PMD.PMD2 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOB-> PMD.PMD3 = 0X03;   // 設為雙向,和51_IO 相同

    GPIOB-> PMD.PMD4 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOB-> PMD.PMD5 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOB-> PMD.PMD6 = 0X03;   // 設為雙向,和51_IO 相同
    GPIOB-> PMD.PMD7 = 0X03;   // 設為雙向,和51_IO 相同

//--設定time0 啟動time0中斷
     Timer_initial();
//--設定time0 啟動time0中斷    
     
 GPB_DMASK=0xff00;
 User1.Config.bibi_1=0;  
 while (1)
  {

     if (scan_cnt>3) scan_cnt=0x00;
     switch(scan_cnt)
       {case 0:
                   led_segment=0XFF; 
                    _ONE=0x00;
                    _TWO=0x01;
                    _THREE=0X01;
                    _FOUR=0X01;

               
                    if(User1.Config._05sec==1){led_segment= _7_seg[disp_0]&0x7f;} //
                     else {led_segment= _7_seg[disp_0]|0x80;}

                //    led_segment= _7_seg[disp_0] ;
               scan_cnt ++ ;
                    break;

        case 1:
                    led_segment=0XFF;
                    _ONE=0x01;
                    _TWO=0x00;
                    _THREE=0X01;
                    _FOUR=0X01;

                    if(User1.Config._05sec==1){led_segment= _7_seg[disp_1]&0x7f;} // 
                     else {led_segment= _7_seg[disp_1]|0x80;}
                //    led_segment= _7_seg[disp_1] ;
                    scan_cnt ++ ;
                    break;
                    
        case 2:
                    led_segment=0XFF;
                    _ONE=0x01;
                    _TWO=0x01;
                    _THREE=0X00;
                    _FOUR=0X01;

                   led_segment= _7_seg[disp_2] ; 

                    scan_cnt ++ ;
                    break;
        case 3:
                    led_segment=0XFF;
                    _ONE=0x01;
                    _TWO=0x01;
                    _THREE=0X01;
                    _FOUR=0X00;

                    led_segment= _7_seg[disp_3] ;  
                    scan_cnt ++ ;
                    break;
        } 
                    disp_0 = time_cnt % 10 ;  
                    disp_1 = (time_cnt/10)%10 ;  
    
                    disp_2= (min_cnt%10); 
                    disp_3 = (min_cnt/10)%10 ; 
                     
  }
 }