STM8S的編譯器Comic支援system call所以UART初始化後,UART的Tx可以直接使用printf(),那Rx可以使用char getinput(void);函數或是讀取flag的值.
1. 整個project的程式檔案目錄如下圖所示.
2. main.c
/***********************************************/
#include "stm8s_003x.h"
#include "stm8s_type.h"
#include "uart.h"
#include <stdio.h>
u8 i = 10;
int main(void)
{
UART_CLKInit();
UART_GPIOInit();
UART1_Init();
enableInterrupts(); //InterruptInit
printf("Hello World.\n\r");
printf("Value = %d \n\r", i);
return 0;
}
@far @interrupt void UART1_RX_IRQHandler (void)
{
flag = UART1->DR; //Auto clear RXNE bit
UART1->SR &= 0xDF; //Clear RXNE by write 0 to it
}
@far @interrupt void UART1_TX_IRQHandler (void)
{
flag = UART1->DR;
}
/***********************************************/
3. stm8_interrupt_vector.c
/***********************************************/
/* 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;
}
extern void _stext(); /* startup routine */
extern @far @interrupt void UART1_TX_IRQHandler (void);
extern @far @interrupt void UART1_RX_IRQHandler (void);
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, NonHandledInterrupt}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, NonHandledInterrupt}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, (interrupt_handler_t)UART1_TX_IRQHandler}, /* irq17 */
{0x82, (interrupt_handler_t)UART1_RX_IRQHandler}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
/***********************************************/
4. uart.c
/***********************************************/
#include "stm8s_003x.h"
#include "stm8s_type.h"
void UART_CLKInit(void) //initialize the registers of Clock
{
CLK->ECKR |= 0x01; //enable extern clock,only ECKR_HSEEN = 1
CLK->CKDIVR = 0x00; //set prescaler
CLK->PCKENR1 |= 0x08; //enable peripheral clock, only CLK_PCKENR1_3 = 1;
}
void UART_GPIOInit() //initialize the registers of GPIO
{
GPIOD->DDR |= 0x20; //PD5 output, PD6 input
GPIOD->CR1 |= 0x20; //output : push-pull mode ; input: float mode
GPIOD->CR2 |= 0x20; //output at 10 Mhz
}
void UART1_Init(void) //initialize the registers of uart2
{
// UART1->BRR2 = 0x02; //set baud rate at 1200 ; mainClock : 16 000 000
// UART1->BRR1 = 0x68;
UART1->BRR2 = 0x08; //set baud rate at 19200 ; mainClock : 16 000 000
UART1->BRR1 = 0x06;
UART1->CR1 = 0x00; //NO parity PCEN=0,8 data bits M=0,enable UART2 UARTD=0
UART1->CR2 = 0x2C; //wait for you; enable TX and RX TEN=0,REN=0;enable receive interrupt RIEN=1
UART1->CR3 = 0x00; //one stop bits
}
void SendByte(u8 temp) //send one byte by the UART2
{
while(((UART1->SR)&0x80) != 0x80); //estimate if send OK
UART1->DR = temp;
}
char putchar(char c) //Retargets the C library printf function to the UART2
{
SendByte((u8)c); //Write a character to the UART1
while((UART1->SR & 0x40) != 0x40); //Loop until the end of transmission
UART1->SR &= 0xBF; //clear TC bit by write 0 to it
return(c);
}
char getinput(void)
{
volatile char input;
return(input);
}
/***********************************************/
5. stm8s_003x.h
/***********************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM8_003x_H
#define __STM8_003x_H
#include "stm8s_type.h"
/******************************************************************************/
/* Library configuration section */
/******************************************************************************/
/******************************************************************************/
/* Peripherals Base Address */
/******************************************************************************/
#define GPIOA_BaseAddress 0x5000
#define GPIOB_BaseAddress 0x5005
#define GPIOC_BaseAddress 0x500A
#define GPIOD_BaseAddress 0x500F
#define GPIOE_BaseAddress 0x5014
#define GPIOF_BaseAddress 0x5019
#define GPIOF_BaseAddress 0x5019
#define FLASH_BaseAddress 0x505A
#define ITC_BaseAddress 0x50A0
#define RST_BaseAddress 0x50B3
#define CLK_BaseAddress 0x50C3
#define WWDG_BaseAddress 0x50D1
#define IWDG_BaseAddress 0x50E0
#define AWU_BaseAddress 0x50F0
#define BEEP_BaseAddress 0x50F3
#define SPI_BaseAddress 0x5200
#define I2C_BaseAddress 0x5210
#define UART1_BaseAddress 0x5230
#define TIM1_BaseAddress 0x5250
#define TIM2_BaseAddress 0x5300
#define TIM4_BaseAddress 0x5340
#define ADC1_BaseAddress 0x53E0
/******************************************************************************/
/* Peripherals declarations */
/******************************************************************************/
#define GPIOA ((GPIO_TypeDef *) GPIOA_BaseAddress)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BaseAddress)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BaseAddress)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BaseAddress)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BaseAddress)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BaseAddress)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BaseAddress)
#define FLASH ((FLASH_TypeDef *) FLASH_BaseAddress)
#define ITC ((ITC_TypeDef *) ITC_BaseAddress)
#define RST ((RST_TypeDef *) RST_BaseAddress)
#define CLK ((CLK_TypeDef *) CLK_BaseAddress)
#define WWDG ((WWDG_TypeDef *) WWDG_BaseAddress)
#define IWDG ((IWDG_TypeDef *) IWDG_BaseAddress)
#define AWU ((AWU_TypeDef *) AWU_BaseAddress)
#define BEEP ((BEEP_TypeDef *) BEEP_BaseAddress)
#define SPI ((SPI_TypeDef *) SPI_BaseAddress)
#define I2C ((I2C_TypeDef *) I2C_BaseAddress)
#define UART1 ((UART1_TypeDef *) UART1_BaseAddress)
#define TIM1 ((TIM1_TypeDef *) TIM1_BaseAddress)
#define TIM2 ((TIM2_TypeDef *) TIM2_BaseAddress)
#define TIM4 ((TIM4_TypeDef *) TIM4_BaseAddress)
#define ADC1 ((ADC1_TypeDef *) ADC1_BaseAddress)
/******************************************************************************/
/* IP registers structures */
/******************************************************************************/
#define enableInterrupts() {_asm("rim\n");} /* enable interrupts */
#define disableInterrupts() {_asm("sim\n");} /* disable interrupts */
/* @brief General Purpose I/Os (GPIO) */
typedef struct GPIO_struct
{
vu8 ODR; /*!< Output Data Register */
vu8 IDR; /*!< Input Data Register */
vu8 DDR; /*!< Data Direction Register */
vu8 CR1; /*!< Configuration Register 1 */
vu8 CR2; /*!< Configuration Register 2 */
}GPIO_TypeDef;
/* @brief Clock Controller (CLK) */
typedef struct CLK_struct
{
vu8 ICKR; /*!< Internal Clocks Control Register */
vu8 ECKR; /*!< External Clocks Control Register */
u8 RESERVED; /*!< Reserved byte */
vu8 CMSR; /*!< Clock Master Status Register */
vu8 SWR; /*!< Clock Master Switch Register */
vu8 SWCR; /*!< Switch Control Register */
vu8 CKDIVR; /*!< Clock Divider Register */
vu8 PCKENR1; /*!< Peripheral Clock Gating Register 1 */
vu8 CSSR; /*!< Clock Security Sytem Register */
vu8 CCOR; /*!< Configurable Clock Output Register */
vu8 PCKENR2; /*!< Peripheral Clock Gating Register 2 */
vu8 CANCCR; /*!< CAN external clock control Register (exist only in STM8S208 otherwise it is reserved) */
vu8 HSITRIMR; /*!< HSI Calibration Trimmer Register */
vu8 SWIMCCR; /*!< SWIM clock control register */
}CLK_TypeDef;
/* @brief Universal Synchronous Asynchronous Receiver Transmitter (UART1) */
typedef struct UART1_struct
{
vu8 SR; /*!< UART1 status register */
vu8 DR; /*!< UART1 data register */
vu8 BRR1; /*!< UART1 baud rate register */
vu8 BRR2; /*!< UART1 DIV mantissa[11:8] SCIDIV fraction */
vu8 CR1; /*!< UART1 control register 1 */
vu8 CR2; /*!< UART1 control register 2 */
vu8 CR3; /*!< UART1 control register 3 */
vu8 CR4; /*!< UART1 control register 4 */
vu8 CR5; /*!< UART1 control register 5 */
vu8 CR6; /*!< UART1 control register 6 */
vu8 GTR; /*!< UART1 guard time register */
vu8 PSCR; /*!< UART1 prescaler register */
}UART1_TypeDef;
#endif /* __STM8S_003x_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
/***********************************************/
6. stm8s_type.h
/***********************************************/
/**
******************************************************************************
* @file stm8s_type.h
* @brief This file contains all common data types.
* @author STMicroelectronics - MCD Application Team
* @version V1.1.1
* @date 06/05/2009
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2>
* @image html logo.bmp
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM8S_TYPE_H
#define __STM8S_TYPE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef signed long const sc32; /* Read Only */
typedef signed short const sc16; /* Read Only */
typedef signed char const sc8; /* Read Only */
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef volatile signed long const vsc32; /* Read Only */
typedef volatile signed short const vsc16; /* Read Only */
typedef volatile signed char const vsc8; /* Read Only */
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
typedef enum
{
FALSE = 0,
TRUE = !FALSE
}bool;
typedef enum
{
RESET = 0,
SET = !RESET
}FlagStatus, ITStatus, BitStatus;
typedef enum
{
DISABLE = 0,
ENABLE = !DISABLE
}FunctionalState;
#define IS_FUNCTIONALSTATE_OK(VALUE) ( (VALUE == ENABLE) || (VALUE == DISABLE) )
typedef enum
{
ERROR = 0,
SUCCESS = !ERROR
}ErrorStatus;
#define U8_MAX ((u8)255)
#define S8_MAX ((s8)127)
#define S8_MIN ((s8)-128)
#define U16_MAX ((u16)65535u)
#define S16_MAX ((s16)32767)
#define S16_MIN ((s16)-32768)
#define U32_MAX ((u32)4294967295uL)
#define S32_MAX ((s32)2147483647)
#define S32_MIN ((s32)-2147483648)
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __STM8S_TYPE_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
/***********************************************/
7. uart.h
/***********************************************/
#include "stm8s_type.h"
void UART_CLKInit(void);
void UART_GPIOInit(void);
void UART1_Init(void);
void SendByte(u8 temp);
char putchar(char c);
char getinput(void);
u8 flag = 0;
/***********************************************/
你好,我剛接觸STM8S,使用STVD+cosmic開發,目前遇到一個問題,就是用timer4中斷,用start debugging之後發現它一直在中斷副程式RUN而跳不出去,請問是哪裡出了問題?我的程式如下
回覆刪除main.c
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "iostm8s.h"
void delayms(unsigned int ms)
{
unsigned char i;
while(ms != 0)
{
for(i=0;i<250;i++)
{
}
for(i=0;i<75;i++)
{
}
ms--;
}
}
main()
{
CLK_SWR=0xe1;
//CLK_CKDIVR=0x08;
PA_DDR=0b00001110;
PA_CR1=0b00001110;
PA_CR2=0x00;
PB_DDR=0b00100000;
PB_CR1=0b00100000;
PB_CR2=0x00;
PC_DDR=0b00101000;
PC_CR1=0b00101000;
PC_CR2=0x00;
PD_DDR=0b00000110;
PD_CR1=0b00000110;
PD_CR2=0x00;
//TMR4 setting
TIM4_IER=0x00;
TIM4_EGR=0x01;
TIM4_PSCR=0x07;
TIM4_ARR=255;
TIM4_CNTR=255;
TIM4_CR1=0x01;
TIM4_IER=0x01;
//TMR4 setting
_asm("rim"); //Enable interrupt (level 0 set)
while (1)
{
//PA_ODR=PA_ODR | 0b00001110;
//delayms(200);
//PA_ODR=PA_ODR & 0b11110001;
PB_ODR=PB_ODR | 0b00100000;
//delayms(200);
PB_ODR=PB_ODR & 0b11011111;
PC_ODR=PC_ODR | 0b00101000;
//delayms(200);
PC_ODR=PC_ODR & 0b11010111;
//delayms(200);
PD_ODR=PD_ODR | 0b00000110;
//delayms(200);
PD_ODR=PD_ODR & 0b11111001;
}
}
@far @interrupt void tmr4_interrupt(void)
{
TIM4_SR=0x00;
PA_ODR=PA_ODR ^ 0x02;
//return;
}
stm8s_interrupt_vector.c
/* 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
*/
//PA_ODR=PA_ODR ^ 0x02;
return;
}
extern void main();//_stext(); /* startup routine */
extern @far @interrupt void tmr4_interrupt(void);
//extern @interrupt void tmr4_interrupt(void);
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)main},//_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, NonHandledInterrupt}, /* 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, (interrupt_handler_t)tmr4_interrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
Hi Gary Goole:
回覆刪除這是因為你在一開始Time4的"TIM4_CR1=0x01;"就enable,所以Time4會不停的計數,而執行到了Time4中斷時,
@far @interrupt void tmr4_interrupt(void)
{
TIM4_SR=0x00
又將Time4重置,MCU內部的的時脈(Clock)不會因為你進入Debug mode就停止下來,所以你進入Debug mode時,你按一次單步的動作,Time4早就計數完畢,所以你就會覺得一直停留在中斷副程式中.
你好,感謝你的解答,我會用debug mode就是因為main.c主程式裡的其他指令都沒有執行,我才會用debug mode去除錯,我用示波器看PA1的狀態Hi,Lo狀態個約9us,這是什麼原因讓程式一直在中斷副程式RUN而沒有跳到main主程式,希望你能解答我的困惑?
刪除Hi Gary Goole:
刪除請教您是學生還是已經在上班的工程師,我想了解一下,因為是學生的話可能就要給您說明詳細一點,如果是工程師您可能要先了解一下,Time在IC內部硬體的工作原理,這樣會對你在使用Time4上會比較有幫助.
您在enable Time4後,程式中斷優先權是Time4,所以Time4會優先執行,而你在Time4中斷裡只是將值重置,之後的程式並沒有關閉Time4,因此程式會重複執行Time4的中斷程序,要在Debug mode看到從Time4中斷程序中跳出來,就要將Time4 Disable.
我給您先寫段範例,請將您的程式增加到//Add your program features.
void TIM4_Init(void)
{
CLK->PCKENR1 &= 0x10; // TIM4 clock enable
TIM4->ARR = 0x80; // Init time4 1ms interrupts
TIM4->PSCR = 7; //Prescaler value
TIM4->IER = 1; //Update interrupt enabled
//TIM4->CR1 = 0x01; //Counter enable
TIM4->CR1 = 0x00; //Counter disable
}
int main(void)
{
TIM4_Init();
enableInterrupts(); //InterruptInit
while(1)
{
TIM4->CR1 = 0x01; //Counter enable
//Add your program features.
TIM4->CR1 = 0x00; //Counter disable
}
return 0;
}
@far @interrupt void TIM4InterruptHandle (void)
{
TIM4->SR = 0; //Status register
//TIF: No trigger event has occurred
//UIF: No update has occurred
//Add your program features.
}
你好,我不是學生,只是目前有一個案子廠商指定要用STM8S003,我沒用過ST MCU,先前都是用microchip,holtek,這個程式我只是測試一下interrupt的寫法,原本是主程式delayms(200)去延遲,後來改成用中斷方式,只是結果不是我所預期,它不是會自動載入嗎?應該會重新計數,怎麼感覺從中斷跳出去之後又跳進中斷,請問依照你上頭所說來改,就能讓PA1 Hi,Lo的時間嗎?
刪除喔~~PIC與8051指令集.
刪除ST MCU 硬體架構比較類似現在32bit MCU的架構.
你要持續讓GPIO output Hi or Lo,可以在main()下觸發Time4中斷後,將GPIO控制的程式放在
@far @interrupt void TIM4InterruptHandle (void)
{
//Add your program features.
}
,我之前有用過偉詮電子的MCU,我發現各家的硬體設計多多少少都有些差異,除非都是跟同一家IP(創意電子 or 智原科技)公司買來的.
你好,你的意思是若要持續計數的話(也就是固定時間產生中斷一次),就需再中斷副程式裡增加
刪除TIM4_SR=0;
TIM4_CR1=0x00;
TIM4_CR1=0x01;
這樣使TIM4 disable再使其enable,TIM4_ARR的值才會再載入counter計數?我這樣說對嗎?
請問一下,您現在是要讓GPIO_A的第二pin持續輸出一個很精準時脈的方波,是嗎?
刪除對,沒錯,雖然clock是由內部提供,但還是希望在成本考量下盡量精準。
刪除TIM4->SR = 0; //Clear Flag
刪除就已經是將旗標清除,旗標清除後Time4的counter就會重新計數,
我覺得你可以參考下列的寫法看看可不可以用:
int main(void)
{
GPIOA_Init();
TIM4_Init();
enableInterrupts(); //InterruptInit
while(1)
{
TIM4->CR1 = 0x01; //Counter enable
GPIOA->ODR |= 0x08; //Hi
TIM4->CR1 = 0x01; //Counter enable
GPIOA->ODR &= ~(0x08); //Lo
}
return 0;
}
@far @interrupt void TIM4InterruptHandle (void)
{
TIM4->SR = 0; //Clear Flag
}
你好,我是過你的方法一樣不行,先前我用debug mode時發現它一進中斷副程式就會在中斷副程式裡RUN無法返回主程式,依你的經驗可告知是那出錯了嗎?以下是我的程式碼
刪除main.c
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "iostm8s.h"
void delayms(unsigned int ms)
{
unsigned char i;
while(ms != 0)
{
for(i=0;i<250;i++)
{
}
for(i=0;i<75;i++)
{
}
ms--;
}
}
main()
{
CLK_SWR=0xe1;
//CLK_CKDIVR=0x08;
PA_DDR=0b00001110;
PA_CR1=0b00001110;
PA_CR2=0x00;
PB_DDR=0b00100000;
PB_CR1=0b00100000;
PB_CR2=0x00;
PC_DDR=0b00101000;
PC_CR1=0b00101000;
PC_CR2=0x00;
PD_DDR=0b00000110;
PD_CR1=0b00000110;
PD_CR2=0x00;
//TMR4 setting
TIM4_IER=0x00;
CLK_PCKENR1=0x10;
TIM4_EGR=0x01;
TIM4_PSCR=0x07;
TIM4_ARR=0x80;//250;
//TIM4_CNTR=250;
TIM4_CR1=0x00;//0x01;
TIM4_IER=0x01;
//TMR4 setting
_asm("rim"); //Enable interrupt (level 0 set)
while (1)
{
//PA_ODR=PA_ODR | 0b00001110;
//delayms(200);
//PA_ODR=PA_ODR & 0b11110001;
/*PB_ODR=PB_ODR | 0b00100000;
delayms(200);
PB_ODR=PB_ODR & 0b11011111;
PC_ODR=PC_ODR | 0b00101000;
delayms(200);
PC_ODR=PC_ODR & 0b11010111;
delayms(200);
PD_ODR=PD_ODR | 0b00000110;
delayms(200);
PD_ODR=PD_ODR & 0b11111001;
delayms(200);*/
TIM4_CR1=0x01;
PA_ODR=PA_ODR | 0b00000010;
TIM4_CR1=0x01;
PA_ODR=PA_ODR & 0b11111101;
}
}
@far @interrupt void tmr4_interrupt(void)
{
TIM4_SR=0x00;
//PA_ODR=PA_ODR ^ 0x02;
//TIM4_CR1=0x00;
//TIM4_CR1=0x01;
//return;
}
stm8_interrupt_vector.c
/* 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
*/
//PA_ODR=PA_ODR ^ 0x02;
return;
}
extern void main();//_stext(); /* startup routine */
extern @far @interrupt void tmr4_interrupt(void);
//extern @interrupt void tmr4_interrupt(void);
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)main},//_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, NonHandledInterrupt}, /* 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, (interrupt_handler_t)tmr4_interrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
我的範例都是驗證過的因該沒有什麼問題,
刪除你可以列出你TIME4
#define TIM4 ((TIM4_TypeDef *) TIM4_BaseAddress)
和
/* @brief 8-bit system timer (TIM4) */
typedef struct TIM4_struct
{
vu8 CR1; /*!< control register 1 */
u8 RESERVED1; /*!< Reserved1 byte */
u8 RESERVED2; /*!< Reserved2 byte */
vu8 IER; /*!< interrupt enable register */
vu8 SR; /*!< status register */
vu8 EGR; /*!< event generation register */
vu8 CNTR; /*!< counter register */
vu8 PSCR; /*!< prescaler register */
vu8 ARR; /*!< auto-reload register */
}TIM4_TypeDef;
這部分的程式碼嗎?
STM8S不同的型號的IC TIME4的暫存器會有差異.
你好,我沒用類似你用的結構方式,我是直接與暫存器溝通,你應該不是用COSMIC C complier吧
刪除1. 抱歉!請教一下,為什麼您會覺得我不是使用COSMIC C Compiler呢?
刪除2. 您可以列出Time4 暫存器的#define設定這部分的code嗎?
1.你好,因為你的結構用法,我參考別人的範例都是我這種寫法,沒看過你這種寫法,因此懷疑你不是用COSMIC。
刪除2.下面所列是我include "iostm8s.h"裡的TIM4定義,提供給你做參考。
/* TIMER 4 section
*/
volatile char TIM4_CR1 @0x5340; /* Control register 1 */
volatile char TIM4_IER @0x5341; /* Interrupt enable reg */
volatile char TIM4_SR @0x5342; /* Status register */
volatile char TIM4_EGR @0x5343; /* Event Generation reg */
volatile char TIM4_CNTR @0x5344; /* Counter register */
volatile char TIM4_PSCR @0x5345; /* Prescaler register */
volatile char TIM4_ARR @0x5346; /* Auto-reload register */
1. 我想結構的寫法是標準C/C++語言的語法,可能是您比較少用,不過ST的範例都是這樣寫的,我這部分是依照ST的範例做的.
刪除2. 你的MCU型號是STM8S003系列的嗎?
如果是的話,你的設定就錯啦,請參考ST的文件DM00024550.pdf,第page 34,STM8S003的MCU Time4暫存器設定如下所示.
TIME4_CR1 = 0x005340
Reserved = 0x005341
Reserved = 0x005342
TIME4_IER = 0x005343
TIME4_SR = 0x005344
TIME4_EGR = 0x005345
TIME4_CNTR = 0x005346
TIME4_PSCR = 0x005347
TIME4_ARR = 0x005348
你好,感謝你的回覆,還好有你的幫忙,我查了一下確實如你所說,TIM4的暫存器位址確實定義錯了,我是找C:\Program Files (x86)\COSMIC\CXSTM8_32K\Hstm8底下的iostm8s.h,因為裡頭我找不到stm8s003.h檔,因此找一個叫相近的檔案也沒想那麼多,但問題來了,難道我要一個一個去修改暫存器的位址嗎?
回覆刪除你好,問題已經解決了,我看了資料stm8s003與stm8s103暫存器位址是一樣,所以我include stm8s103.h,非常感謝你這兩天的協助。
回覆刪除你好,請教一下,TIM4的中斷有兩個條件,一是overflow另一個是寫入TIME4_CNTR,我看了資料也試了很多方法,但就是無法寫入TIME4_CNTR時不產生中斷,請問有什麼方法可以解決這個問題嗎?TIM4中斷我只想overflow產生中斷,寫入TIME4_CNTR不產生中斷。
回覆刪除1. 請教一下,您可以秀出您的TIME4初始化設定值嗎?
刪除2. 因為我之前使用他家的MCU Time時都習慣使用向下計數,假設初始值是0x8000向下計數至0x0000為1s就會產生一個flag中斷信號,清除flag後又會重新計數.
sorry,是我誤會了,原以為它是像下計數,後來用debug才知道實際上是up counter,TIM4_CNTR會跟TIM4_ARR做比較,實際上寫入TIM4_CNTR是不會產生中斷。
刪除從您之前的留言看來,您是設定成向上計數,
刪除你要改向下計數也是可以, TIME4_CR1的 URS初始值設1,就可以了.
Bit 2 URS: Update request source
0: When enabled, an update interrupt request is sent as soon as registers are updated (counter
overflow).
1: When enabled, an update interrupt request is sent only when the counter reaches the
overflow/underflow.
再次請教,我要將PB5設成digital input and pull up,程式設定如下
刪除PB_DDR=0b00000000;
PB_CR1=0b00110000; //Input with pull-up
PB_CR2=0x00; //PB External interrupt disabled
但我量PB5 pin腳(PB5空接)並沒有量到+5V的電壓,量到的是0V,這是怎麼回事?
GPIO當做input時,是不可以float的,請將PB5接個Pull high電阻(4.7k歐姆)至VDD.
刪除可是我看stm8s003 datasheet,其Px_CR1若設為1則為pull-up,也就是內部提昇電阻啟動了,下面是Px_CR1的說明。
刪除In input mode (DDR = 0):
0: Floating input
1: Input with pull-up
你好,已經找到問題點了,在stm8s003p3 datasheet P19有說明PB4,PB5為true open-drain I/O,所以無法設pull-up。
回覆刪除下列的意見您可以參考看看:
刪除您可以看一下ST文件DM00024550.pdf page26~27,
其中每的portP?_IDR Port ? input pin value register 0xXX(1),
都會有" 0xXX(1)",
他有個註解是這樣寫的" (1)Depends on the external circuitry."
所以您再參考DM0004010.pdf, page17的電路圖,PB7的輸入也是這樣設計的,
你好,請教一下,有關於EEPROM的寫入或讀取,有沒有比下面我寫的還要更好得方式,我寫的會造成短暫時間的無窮迴圈,這並不是一個好得方式,而且對EEPROM做讀寫動作時,中斷似乎會被暫停。
回覆刪除do
{
FLASH_DUKR=0xae;
FLASH_DUKR=0x56;
}while(_DUL==0);
eeprom_lig_on1=lig_on1_on_count;
_DUL=0;
您這顆的EEPROM的型號是?
刪除是STM8S003P3 MCU內部的EEPROM
刪除STM8S的EEPROM 我是沒有用過啦,
刪除不過在你的說明下我大致了解您的問題,
依照您的寫法,當_DUL==0之前,
FLASH_DUKR=0xae;
FLASH_DUKR=0x56;
這兩行程式會被重複執行對嗎,您覺得這樣不好是嗎?
如果是這樣,您就直接改成,
FLASH_DUKR=0xae; //只會執行一次.
FLASH_DUKR=0x56; //只會執行一次.
while(_DUL==0); //當_DUL為0時,才會執行下一行指令.
eeprom_lig_on1=lig_on1_on_count;
感謝你的回覆,我已經詢問過ST FAE,寫入EEPROM時需6ms的時間,且寫入期間不允許任何的中斷,也就是這6ms程式等於在當機狀態
刪除你好,請教PWM問題,我使用TIM1 channel 3輸出PWM訊號,以下是原始檔,但在輸出端pin13 PORT c3(stm8s003)量不到pwm訊號,請教是哪兒出了問題?感謝你
回覆刪除/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "iostm8s103.h"
_Bool PA1 @PA_ODR:1;
_Bool PD2 @PD_ODR:2;
void delayms(unsigned int ms)
{
unsigned char i;
while(ms != 0)
{
for(i=0;i<250;i++)
{
}
for(i=0;i<75;i++)
{
}
ms--;
}
}
main()
{
CLK_SWR=0xe1; //fhsi=16MHz
CLK_CKDIVR=0x10; //fhsi/4=4MHz
PA_DDR=0b00001110;
PA_CR1=0b00001110;
PA_CR2=0x00;
PB_DDR=0b00100000;
PB_CR1=0b00100000;
PB_CR2=0x00;
PC_DDR=0b00101000;
PC_CR1=0b00101000;
PC_CR2=0x00;
PD_DDR=0b00001110;
PD_CR1=0b00001110;
PD_CR2=0x00;
//TMR4 setting
TIM4_IER=0x00;
CLK_PCKENR1=0x10;
TIM4_EGR=0x01;
TIM4_PSCR=0x07; //Fosc/128=4MHz/128=31.25KHz
TIM4_ARR=2; //31.25k/10k=3.125
//TIM4_CNTR=250;
TIM4_CR1=0x01;
TIM4_IER=0x01;
//TMR4 setting
//TIM2 setting
TIM2_CCMR2=0x78;//TIM2_CCMR2 | 0x70;
TIM2_CCER1=TIM2_CCER1 | 0x30;
TIM2_ARRH=0;
TIM2_ARRL=0xff;
TIM2_CCR2H=0;
TIM2_CCR2L=0;
TIM2_PSCR=0;
TIM2_CR1=TIM2_CR1 | 0x01;
//TIM2 setting
//TIM1 setting
TIM1_CR1 =TIM1_CR1 & 0xfe;
TIM1_PSCRH=0;
TIM1_PSCRL=0;
TIM1_ARRH=0;
TIM1_ARRL=49;
TIM1_CR1=TIM1_CR1 | 0x80;
TIM1_EGR=TIM1_EGR | 0x01;
TIM1_CCR3H=0;
TIM1_CCR3L=25;
TIM1_CCMR3=104;
TIM1_CCER2=TIM1_CCER2 | 0x01;
TIM1_CR1=TIM1_CR1 | 0x01;
TIM1_BKR=TIM1_BKR | 0x80;
//TIM1 setting
_asm("rim"); //Enable interrupt (level 0 set)
TIM2_CCR2H=0;
TIM2_CCR2L=12;
while (1)
{
//PA_ODR=PA_ODR | 0b00001110;
//delayms(200);
//PA_ODR=PA_ODR & 0b11110001;
/*PB_ODR=PB_ODR & 0b11011111;
PB_ODR=PB_ODR | 0b00100000;
//delayms(200);
PB_ODR=PB_ODR & 0b11011111;
PC_ODR=PC_ODR | 0b00101000;
//delayms(200);
PC_ODR=PC_ODR & 0b11010111;
//delayms(200);
PD_ODR=PD_ODR & 0b11111001;
PD_ODR=PD_ODR | 0b00000110;
//delayms(200);
PD_ODR=PD_ODR & 0b11111001;*/
//delayms(200);
//TIM4_CR1=0x01;
//PA_ODR=PA_ODR | 0b00000010;
//TIM4_CR1=0x01;
//PA_ODR=PA_ODR & 0b11111101;
}
}
@far @interrupt void tmr4_interrupt(void)
{
TIM4_SR=0x00;
//PA_ODR=PA_ODR ^ 0x02;
//TIM4_CR1=0x00;
//TIM4_CR1=0x01;
//return;
//PA_ODR=0x00;
//PA_ODR=0x02;
//PA_ODR=0x00;
//PA1=!PA1;
PD2=!PD2;
}
我已經知道怎麼做了,謝謝
刪除