阿乾--移情別戀

關於部落格
無名 啞唬 MSN 天空 我追尋方便的時空,建立我五十歲之後的生活紀錄,...我是草包工程師
  • 204326

    累積人氣

  • 10

    今日人氣

    0

    訂閱人氣

舊物利用--stm8程式練習器

 

回收場發現到  飛利浦黑晶爐的控制器控制電路居然是 stm8的mcu 基於勤儉建軍的傳統,二話不說買了6套回來,為了他花了約2`3倍的費用買了2本書,就
慢慢進入這個MCU的領域,這和8952差異很大!! 這只是一個開始...


RESET 加一個開關方便下載程式!


山寨板 ST-LINK 





 開發用程式使用 ST Visual Develop  下載程式: STVP  參考書籍: STM8單片機自學筆記 & STM8單片機原理與實踐

主程式:

#include "stm8s.h"
#include "stm8s_tim1.h"
#include "stm8s_tim6.h"

#define BUZZER GPIO_PIN_0
void delay(unsigned int time);
void GPIOinit(void);
void GPIOflash(void);
void GPIO10flash(void);
void tim1init(void);//匯總 TIM1 
void tim1svc(void);//中斷服務程式 
void GPIOon (void);


u8 pcdis[]={0xd6,0x14,0xcc,0x5c,0x1e,0x5a,0xda,0x14,0xde,0x5e};
u8 pedis[]={0x01,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x01,0x01};
u8 Temperature,Hundreds,Tens,Units;
u8 PowerOn,ON,OFF,ErrFlag;
unsigned int count1;
unsigned char count6;
u8 ErrCount=0;
u8 Start_Flag=0;

@far @interrupt void TIM1_OVF_IRQ(void);
@far @interrupt void TIM6_OVF_IRQ(void);

void KeyScan(void);
void delay(unsigned int time);
void TransData(void);
void ErrTransData(void);
void Display(void);
void GPIOinit(void);
void tim1init(void);
void tim1svc(void);
void tim6init(void);
void tim6svc(void);

void LED_control(u8 LED);


void main(void)
{
        GPIOinit();
        tim1init();        
  tim6init();
  rim();        
        Temperature=120;

        while(1)
        {
        KeyScan();
        if(ErrFlag)
        ErrTransData();
        else
        TransData();
        Display();
        }
}

void KeyScan(void)
{
        GPIO_WriteLow(GPIOD,GPIO_PIN_2);
        GPIO_WriteLow(GPIOD,GPIO_PIN_3);
        GPIO_WriteLow(GPIOD,GPIO_PIN_4);
        GPIO_WriteLow(GPIOD,GPIO_PIN_5);        
        GPIO_Init(GPIOC,(GPIO_PIN_6|GPIO_PIN_7),GPIO_MODE_IN_PU_NO_IT);//變更 sw4 sw5 成為 input

        if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_7)==0)//PC7 press
        {
        delay(50);
        if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_7)==0)
        {
                while(GPIO_ReadInputPin(GPIOC,GPIO_PIN_7)==0);
                Temperature -=10;
        }        
  }

        
        if(GPIO_ReadInputPin(GPIOB,GPIO_PIN_3)==0)
        {
        delay(50);
        if(GPIO_ReadInputPin(GPIOB,GPIO_PIN_3)==0)
        {
                while(GPIO_ReadInputPin(GPIOB,GPIO_PIN_3)==0);
                Start_Flag = !Start_Flag;
        }
}
        
        if(GPIO_ReadInputPin(GPIOA,GPIO_PIN_1)==0)
        {
        delay(50);
        if(GPIO_ReadInputPin(GPIOA,GPIO_PIN_1)==0)
        {
                while(GPIO_ReadInputPin(GPIOA,GPIO_PIN_1)==0);
                Temperature+=1;
        }
}
        if(GPIO_ReadInputPin(GPIOA,GPIO_PIN_3)==0)
        {
        delay(50);
        if(GPIO_ReadInputPin(GPIOA,GPIO_PIN_3)==0)
        {
                while(GPIO_ReadInputPin(GPIOA,GPIO_PIN_3)==0);
                Temperature+=10;
        }
}


        if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_6)==0)//PC6 press
        {
        delay(50);
        if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_6)==0)
        {
                while(GPIO_ReadInputPin(GPIOC,GPIO_PIN_6)==0);
                Temperature -=1;
                ErrCount++;
        }        
  }
        

}


void delay(unsigned int time)
{
        while(time--);
}

void TransData(void)
{
        Hundreds=Temperature/100;
        Tens=(Temperature%100)/10;
        Units=Temperature%10;
}

void ErrTransData(void)
{
        Hundreds=ErrCount/100;
        Tens=(ErrCount%100)/10;
  Units=ErrCount%10;
}

void Display(void)
{
        
        GPIO_Init(GPIOC,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY 7SEGMENT
        //GPIO_Init(GPIOD,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY 3DIGIT
//        GPIO_Init(GPIOD,(GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5),GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY 3DIGIT
//        GPIO_Init(GPIOE,GPIO_PIN_5,GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY SEGMENT A
        GPIO_WriteLow(GPIOE,GPIO_PIN_5);

        
        if(Hundreds>0)
        {
                GPIO_Write(GPIOC,pcdis[Hundreds]);
                        if(pedis[Hundreds])
                                GPIO_WriteHigh(GPIOE,GPIO_PIN_5);
                                else
                                GPIO_WriteLow(GPIOE,GPIO_PIN_5);
                        }
                else 
                {
                GPIO_Write(GPIOC,0x00);//百位消零 
                GPIO_WriteLow(GPIOE,GPIO_PIN_5);//去除A節
}
                        GPIO_Write(GPIOD,0x10);//趨動百位數
                        delay(500);                
                        GPIO_WriteLow(GPIOC,GPIO_PIN_ALL);
                        delay(5);

        GPIO_Write(GPIOC,pcdis[Tens]);
        if(pedis[Tens])
        GPIO_WriteHigh(GPIOE,GPIO_PIN_5);
        else
         GPIO_WriteLow(GPIOE,GPIO_PIN_5);


                        GPIO_Write(GPIOD,0x08);//趨動十位數
                        delay(500);
                        GPIO_WriteLow(GPIOC,GPIO_PIN_ALL);
                        delay(5);
        

        GPIO_Write(GPIOC,pcdis[Units]);
        if(pedis[Units])//消除a節問題
        GPIO_WriteHigh(GPIOE,GPIO_PIN_5);
        else
         GPIO_WriteLow(GPIOE,GPIO_PIN_5);
                        GPIO_Write(GPIOD,0x04);//趨動個位數
                        delay(500);
                        GPIO_WriteLow(GPIOC,GPIO_PIN_ALL);//消除殘影
                        delay(5);
        
}


void GPIOinit(void)
{
        GPIO_Init(GPIOC,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY 7SEGMENT
        GPIO_Init(GPIOD,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY 3DIGIT
        GPIO_Init(GPIOE,GPIO_PIN_5,GPIO_MODE_OUT_PP_HIGH_FAST);//DISPLAY SEGMENT A
        GPIO_WriteLow(GPIOE,GPIO_PIN_5);
        GPIO_Init(GPIOA,GPIO_PIN_1|GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//INPUT +/- TIME
        GPIO_Init(GPIOB,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//INPUT + FIRE POWER
        

}



void tim1init(void)
{
TIM1_TimeBaseInit(19,TIM1_COUNTERMODE_UP,50000,0);//2M/20=100khz 除50000次=2hz
TIM1_ITConfig(TIM1_IT_UPDATE,ENABLE);
TIM1_GenerateEvent(TIM1_EVENTSOURCE_UPDATE);
TIM1_Cmd(ENABLE);
}

void tim1svc(void)
{
        if(Start_Flag==1)
        {
   count1++;
   if(count1<10)
   ErrFlag=1;
         else
         ErrFlag=0;
  if (count1==120)
   {
    Temperature--;
                if(Temperature==0)
                {
                  Start_Flag=0;
                }
    count1=0;
    }
   }
        TIM1_ClearFlag(TIM1_FLAG_UPDATE);
}

@far @interrupt void TIM1_OVF_IRQ(void)
{
        tim1svc();
}

@far @interrupt void TIM6_OVF_IRQ(void)
{
        tim6svc();
}


void tim6init(void)
{
        TIM6_TimeBaseInit(TIM6_PRESCALER_32,250);//TIM6_PRESCALER_8 TIM6_TimeBaseInit
        TIM6_SetCounter(250);
        TIM6_ITConfig(TIM6_IT_UPDATE,ENABLE);//2Mhz/8/250
        //rim();
        TIM6_Cmd(ENABLE);
}

void tim6svc(void)
{
count6++;
if (count6==250)//250>>25
{
// GPIO_WriteHigh(GPIOC,GPIO_PIN_5);//LED3 off
count6=0;
if(Start_Flag)
GPIO_WriteHigh(GPIOC,GPIO_PIN_5);//. on 
}
if(Temperature==1)
GPIO_WriteReverse(GPIOD,BUZZER);
        TIM6_ClearITPendingBit(TIM6_IT_UPDATE);
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)

  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %drn", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/



中斷程式:
   /*        BASIC INTERRUPT VECTOR TABLE FOR STM8 devices
*        Copyright (c) 2007 STMicroelectronics
*/

typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {
        unsigned char interrupt_instruction;
        interrupt_handler_t interrupt_handler;
};

@far @interrupt void NonHandledInterrupt (void)
{
        /* in order to detect unexpected events during development, 
           it is recommended to set a breakpoint on the following instruction
        */
        return;
}

@far @interrupt void TIM1_OVF_IRQ(void);
@far @interrupt void TIM6_OVF_IRQ(void);


extern void _stext();     /* startup routine */

struct interrupt_vector const _vectab[] = {
        {0x82, (interrupt_handler_t)_stext}, /* reset */
        {0x82, NonHandledInterrupt}, /* trap  */
        {0x82, NonHandledInterrupt}, /* irq0  */
        {0x82, NonHandledInterrupt}, /* irq1  */
        {0x82, NonHandledInterrupt}, /* irq2  */
        {0x82, NonHandledInterrupt}, /* irq3  */
        {0x82, NonHandledInterrupt}, /* irq4  */
        {0x82, NonHandledInterrupt}, /* irq5  */
        {0x82, NonHandledInterrupt}, /* irq6  */
        {0x82, NonHandledInterrupt}, /* irq7  */
        {0x82, NonHandledInterrupt}, /* irq8  */
        {0x82, NonHandledInterrupt}, /* irq9  */
        {0x82, NonHandledInterrupt}, /* irq10 */
        {0x82, TIM1_OVF_IRQ}, /* irq11 每分鐘計數*/
        {0x82, NonHandledInterrupt}, /* irq12 */
        {0x82, NonHandledInterrupt}, /* irq13 */
        {0x82, NonHandledInterrupt}, /* irq14 */
        {0x82, NonHandledInterrupt}, /* irq15 */
        {0x82, NonHandledInterrupt}, /* irq16 */
        {0x82, NonHandledInterrupt}, /* irq17 */
        {0x82, NonHandledInterrupt}, /* irq18 */
        {0x82, NonHandledInterrupt}, /* irq19 */
        {0x82, NonHandledInterrupt}, /* irq20 */
        {0x82, NonHandledInterrupt}, /* irq21 */
        {0x82, NonHandledInterrupt}, /* irq22 */
        {0x82, TIM6_OVF_IRQ}, /* irq23 led閃爍 */
        {0x82, NonHandledInterrupt}, /* irq24 */
        {0x82, NonHandledInterrupt}, /* irq25 */
        {0x82, NonHandledInterrupt}, /* irq26 */
        {0x82, NonHandledInterrupt}, /* irq27 */
        {0x82, NonHandledInterrupt}, /* irq28 */
        {0x82, NonHandledInterrupt}, /* irq29 */
};

小經驗: STM8 MCU 有很多我使用的 STM8S903K3 這一顆因為腳數少(32PIN),所以定時器沒有 TIM4 ,而書本的範例 STM8S208RB(64PIN) 功能多上許多,當時花了許多時間終於找到問題!!
    這個與 8951不同 有 GPIO 所以很多地方需要單獨設定,有點不習慣!! 最不習慣的事就是 他的語法比較接近"人語",所以要參考的地方還真不少!!  學習時候一邊參考 STM8S/A Standard Peripherals Library 會讓你更了解這個 MCU的庫程式.
相簿設定
標籤設定
相簿狀態