IAR下STM8S207單片機各模塊的無庫例程
[i=s] 本帖最後由 suzhwt 於 2010-9-21 15:57 編輯 [/i]
TIM/ADC/CLOCK/EEPROM/SPI/UART/WWDG/IWDG等不使用庫的應用例程,包含SPI雙機通訊、定時器的捕獲、PWM各功能的實現等;
原理圖有2個錯誤:1,晶振電容爲22P;2,按鍵電容位置錯;
以下模塊全部已調試通過:
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigADC10()
@Br: 配置ADC10
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigADC10( void ){
ADC_CSR = ( 1 << EOCIE )
+ ( 1 << CH02 ) + ( 1 << CH01 ) + ( 1 << CH00 );
/* 中斷使能, 選中CH7 */
ADC_CR2 = ( 1 << ALIGN ); /* 右對齊 */
ADC_CR1 = ( 1 << SPSEL02 ) + ( 1 << SPSEL01 ) + ( 1 << SPSEL00 )
+ ( 1 << CONT ) + ( 1 << ADON );
/* Fadc = Fmaster / 18, 持續轉換, ADON寫1喚醒ADC */
ADC_CR1 |= ( 1 << ADON ); /* 當ADON爲1時再寫1則啓動轉換 */
}
suzhwt 發表於 2010-9-21 15:43
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigClock()
@Br: 配置處理器的時鐘
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigClock( void ){
CLK_ICKR = ( 1 << HSIEN ); /* 使能內部高速RC OSC */
CLK_ECKR = ( 1 << HSEEN ); /* 打開外部晶體振盪器 */
while(( CLK_ECKR & 0x02 ) == 0 ); /* ( 1 << HSERDY ) */
CLK_SWR = F_MASTER_HSE; /* 指定切換的HSE主時鐘 */
while(( CLK_SWCR & 0x08 ) == 0 ); /* ( 1 << SWIF ) */
CLK_SWCR |= ( 1 << SWEN ); /* 執行切換 */
CLK_CKDIVR = 0x00; /* Fcpu = Fmaster = 18MHz */
CLK_PCKENR1 = ( 1 << TM1_CLK_ENABLE )
+ ( 1 << TM3_CLK_ENABLE )
+ ( 1 << TM2_CLK_ENABLE )
+ ( 1 << TM4_CLK_ENABLE )
+ ( 1 << UART1_CLK_ENABLE )
+ ( 1 << SPI_CLK_ENABLE );
CLK_PCKENR2 = ( 1 << ADC_CLK_ENABLE );
}
suzhwt 發表於 2010-9-21 15:43
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
#define FIRST_SECURITY_KEY 0xAE
#define SECOND_SECURITY_KEY 0x56
#define ADD_EEPROM_S8 0x4000
/* STM8S207S8的CODE空間爲64K,而EEPROM的大小爲1536字節,即:3頁 * 512節/頁 */
/* EEPROM的KEY寫入與FLASH的KEY正好相反 */
/*****************************************************
@Fn: InitialFlashReg()
@Br: 初始化閃存寄存器組
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void InitialFlashReg( void ){
FLASH_CR1 = FLASH_CR1_RESET_VALUE;
FLASH_CR2 = FLASH_CR2_RESET_VALUE;
FLASH_NCR2 = FLASH_NCR2_RESET_VALUE;
FLASH_IAPSR &= ( uchar )(~( 1 << DUL )); /* 清除只讀DATA區解鎖 */
FLASH_IAPSR &= ( uchar )(~( 1 << PUL )); /* 清除程序區解鎖 */
}
/*****************************************************
@Fn: UnlockFlash()
@Br: 解鎖存儲器
@Pa: 存儲器類型: 不是程序區就是隻讀數據區
@Rt: 無
@Sp: 2個密鑰的操作序列正好相反
*****************************************************/
void UnlockFlash( uchar Type ){
if( Type == UNLOCK_FLASH_TYPE ) /* 解鎖程序區 */
{
FLASH_DUKR = SECOND_SECURITY_KEY;
FLASH_DUKR = FIRST_SECURITY_KEY;
}
else /* 解鎖只讀數據區 */
{
FLASH_DUKR = FIRST_SECURITY_KEY;
FLASH_DUKR = SECOND_SECURITY_KEY;
}
}
/*****************************************************
@Fn: LockFlash()
@Br: 鎖定存儲器
@Pa: 存儲器類型:不是程序區就是隻讀數據區
@Rt: 無
@Sp: 無
*****************************************************/
void LockFlash( uchar Type ){
if( Type == UNLOCK_FLASH_TYPE )
{
FLASH_IAPSR &= ~( 1 << PUL );
}
else
{
FLASH_IAPSR &= ~( 1 << DUL );
}
}
/*****************************************************
@Fn: InitialFlashReg()
@Br: 寫入一字節到指定只讀數據區[EEPROM]
@Pa: 指定EEPROM地址與數據內容
@Rt: 無
@Sp: 無
*****************************************************/
void WriteByteToFLASH( ulong Address, uchar Data ){
*(( __far uchar * ) Address ) = Data;
}
/*****************************************************
@Fn: Write4BytToFlash()
@Br: 寫入4字節到指定EEPROM的連續4字節空間
@Pa: EEPROM地址與LONG型數據內容
@Rt: 無
@Sp: 數據寫入方式爲小端模式
*****************************************************/
void Write4BytToFlash( ulong Address, ulong Data ){
/* Enable Word Write Once */
FLASH_CR2 |= ( 1 << WPRG );
FLASH_NCR2 &= ( uchar )( ~( 1 << NWPRG ));
*((( __far uchar * )Address ) + 3 ) = *(( uchar * )( &Data )); /* Write one byte - from Highest address*/
*((( __far uchar * )Address ) + 2 ) = *(( uchar * )( &Data ) + 1 ); /* Write one byte*/
*((( __far uchar * )Address ) + 1 ) = *(( uchar * )( &Data ) + 2 ); /* Write one byte*/
*(( __far uchar * )Address ) = *(( uchar * )( &Data ) + 3 ); /* Write one byte - from higher address*/
}
/*****************************************************
@Fn: ReadByteEEPROM()
@Br: 從EEPROM中讀取1字節
@Pa: 指定EEPROM地址
@Rt: 讀取的CHAR型內容
@Sp: 無
*****************************************************/
uchar ReadByteEEPROM( ulong Address ){
return(*(( __far uchar* ) Address )); /* Read byte */
}
/*****************************************************
@Fn: Read4BytFromFlash()
@Br: 從EEPROM中讀取連續的4字節
@Pa: 指定EEPROM地址
@Rt: 讀取的LONG內容
@Sp: 小端模式
*****************************************************/
ulong Read4BytFromFlash( ulong Address ){
ulong i;
ulong Temp[2];
Temp[0] = *(( __far uchar * )Address );
Temp[0] |= ( *((( __far uchar * )Address ) + 1 ) << 8 );
Temp[1] = *((( __far uchar * )Address ) + 2 );
Temp[1] |= ( *((( __far uchar * )Address ) + 3 ) << 8 );
i = Temp[0] + ( Temp[1] << 16 );
free( Temp );
return i;
}
/*****************************************************
@Fn: EraseByteFLASH()
@Br: 擦除EEPROM中內容
@Pa: 指定EEPROM地址
@Rt: 無
@Sp: 無
*****************************************************/
void EraseByteFLASH( uint Address ){
*(( __near uchar * ) Address ) = 0x00;
}
void Test( void ){
ulong i;
UnlockFlash( UNLOCK_EEPROM_TYPE );
Write4BytToFlash( ADD_EEPROM_S8, 0x12345678 );
LockFlash( UNLOCK_EEPROM_TYPE );
i = Read4BytFromFlash( ADD_EEPROM_S8 );
i = i;
}
suzhwt 發表於 2010-9-21 15:43
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigPortE()
@Br: 配置端口E
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigPortE( void ){
PE_DDR = ( 1 << PE6 ) + ( 1 << PE5 );
PE_CR1 = 0;
PE_CR2 = 0;
}
/*****************************************************
@Fn: ConfigGPIO()
@Br: 配置端口
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigGPIO( void ){
PG_DDR = 0x03; /* 輸出 */
PG_CR1 = 0x03; /* 推輓模式 */
PG_CR2 = 0x00; /* 速度2MHz */
ConfigPortE();
}
suzhwt 發表於 2010-9-21 15:44
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigIWDG()
@Br: IWDG初始化
@Pa: 無
@Rt: 無
@Sp: 需要選擇字支持
*****************************************************/
void ConfigIWDG( void ){
IWDG_KR = IWDG_KEY_ACCESS; /* 寫入修改值使能鍵值 */
IWDG_PR = ( 1 << IWDG_PR02 ) + ( 1 << IWDG_PR01 ); /* 1.02s時長 */
IWDG_RLR = 0xFF;
IWDG_KR = IWDG_KEY_REFRESH; /* 寫入後恢復到保護狀態 */
IWDG_KR = IWDG_KEY_EBABLE; /* 啓動看門狗 */
}
/*****************************************************
@Fn: ClearIWDG()
@Br: 清看門狗IWDG
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ClearIWDG( void ){
IWDG_KR = IWDG_KEY_REFRESH; /* 清看門狗 */
}
suzhwt 發表於 2010-9-21 15:44
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigInterrupt()
@Br: 配置中斷輸入口
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigInterrupt( void ){
PA_DDR &= ~( 1 << PA6 ); /* 配置爲輸入口 */
PA_CR1 = ( 1 << C16 ); /* 配置上拉電阻 */
PA_CR2 = ( 1 << C26 ); /* 使能中斷 */
CPU_CCR |= ( 1 << I1 ) + ( 1 << I0 ); /* 改爲最高優先級 */
EXTI_CR1 = 0; /* 下降沿和低電平觸發 */
}
suzhwt 發表於 2010-9-21 15:44
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigSPI()
@Br: 配置SPI接口
@Pa: 工作模式
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigSPI( uchar WorkMode ){
SPI_CR1 = 0x00;
SPI_CR2 = ( uchar )( 1 << SSM ); /* SSI位的值代替NSS腳控制從設備的選擇 */
SPI_ICR = 0x00;
SPI_SR = ( uchar )( 1 << SPI_TXE );
SPI_CR1 = ( uchar )(( uchar )( 1 << LSBFIRST )
+ ( uchar )( 1 << BR02 ) /* 波特率 = 2 ^ ( BR[2:0] + 1 ) = Fmaster/32 */
+ ( uchar )( 1 << SPI_CPOL )
+ ( uchar )( 1 << SPI_CPHA ));
if( WorkMode == SPI_MASTER_MODE )
{
SPI_CR2 |= ( uchar )( 1 << SSI );
SPI_CR1 |= ( uchar )( 1 << MSTR );
}
else
{
SPI_CR2 &= ~( uchar )( 1 << SSI );
SPI_CR1 &= ~( uchar )( 1 << MSTR );
}
SPI_ICR |= ( uchar )( 1 << RXIE ); /* 使能SPI接收中斷 */
}
/*****************************************************
@Fn: EnablesSPI()
@Br: SPI狀態
@Pa: 不是打開就是關閉
@Rt: 無
@Sp: 無
*****************************************************/
void EnablesSPI( uchar Type ){
if( Type == SPI_ENABLES )
{
SPI_CR1 |= ( uchar )( 1 << SPE );
}
else
{
SPI_CR1 &= ~( uchar )( 1 << SPE );
}
}
/*****************************************************
@Fn: TransmitBySPI()
@Br: 從SPI傳輸數據
@Pa: 數據組衝以及發送幀的長度
@Rt: 無
@Sp: 無
*****************************************************/
void TransmitBySPI( uchar *Buff, uchar Len ){
for( uchar i = 0; i < Len; i++ )
{
SPI_DR = *Buff++;
while( SPI_SR & ( 1 << TXE ) == 0 );
}
}
suzhwt 發表於 2010-9-21 15:44
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/* Excel2000 expression as: v = sin( DEGREE * PI()/180 ) */
/* 0 degree = 0x024A / 2 = 0x0125 = 293 */
/* 10 degree = 0x0125 + sin10 = 344 */
#define SIN_WAVE_LEN 36
const uint SIN_TABLE[SIN_WAVE_LEN] = {
9376, 9312, 9088, 8752, 8272, 7696,
7040, 6288, 5504, 4688, 3872, 3088,
2352, 1680, 1104, 624, 288, 64,
0, 64, 288, 624, 1104, 1680,
2352, 3088, 3872, 4688, 5504, 6288,
7040, 7696, 8272, 8752, 9088, 9312
};
volatile uchar ucSinIndex = 0;
#pragma vector = TM3CC_VECT
__interrupt void TIM3_UPDATE_ISR( void ){
if( TIM3_SR1 & ( 1 << CC1IF ))
{
TIM3_SR1 &= ~( 1 << CC1IF );
LoadValueOfPWM();
/* 固定脈寬試驗 */
// TIM3_CCR1H = ( uchar )( PERCENT_080 >> 8 );
// TIM3_CCR1L = ( uchar )( PERCENT_080 );
/* F = 30Hz, Duty = 80% High-level */
}
}
/*****************************************************
@Fn: ConfigT3_PWM2()
@Br: Timer3的初始化爲PWM模式1
@Pa: 無
@Rt: 無
@Sp:
Timer2,Timer3,Timer5 是通用16位定時器.
*****************************************************/
void ConfigT3_PWM2( void ){
TIM3_PSCR = ( 1 << PSC02 );
/* Configure TIM3 prescaler = 4 */
/* Fck_cnt = Fck_psc / 2 ^[3:0] */
TIM3_CCMR1 = ( 1 << OC1M02 ) + ( 1 << OC1M01 ) + ( 1 << OC1M00 )
+ ( 1 << OC1PE );
/* 輸出比較1預裝載使能, PWM模式2 */
TIM3_CCER1 = ( 1 << CC1P ) + ( 1 << CC1E );
/* OC1低電平有效, 使能TIM3_CH1引腳功能 */
TIM3_ARRH = 0x2F; /* 確定頻率 */
TIM3_ARRL = 0xFF;
TIM3_CNTRH = 0x24;
TIM3_CNTRL = 0xA0;
/* ARR一定要大於CNT,否則輸出波形不正確 */
TIM3_CCR1H = 0; /* 初始化TIM3_CH1引腳緩衝器爲零 */
TIM3_CCR1L = 0;
TIM3_SR1 &= ~( 1 << CC1IF ); /* 清空中斷標誌 */
TIM3_CR1 = ( 1 << ARPE ) + ( 1 << CEN ); /* 自動重載及計數器使能 */
TIM3_IER = ( 1 << CC1IE ); /* 使能中斷 */
}
/*****************************************************
@Fn: LoadValueOfPWM()
@Br: 載入波表值
@Pa: 無
@Rt: 無
@Sp:
Timer2,Timer3,Timer5 是通用16位定時器.
*****************************************************/
void LoadValueOfPWM( void ){
TIM3_CCR1H = ( uchar )( SIN_TABLE[ ucSinIndex ] >> 8 ); /* 2.5赫正弦波 */
TIM3_CCR1L = ( uchar )( SIN_TABLE[ ucSinIndex ] );
ucSinIndex++;
if( ucSinIndex >= SIN_WAVE_LEN )
{
ucSinIndex = 0;
}
}
suzhwt 發表於 2010-9-21 15:45
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigTimer1()
@Br: 捕獲TIM1CH1[PC1]引腳上按鍵產生的脈衝寬度.
@Pa: 無
@Rt: 無
@Sp: 無
* 時鐘在CLK_PCKENR1中被關閉時所有設置不能寫入到寄存器中.
* Timer1 是高級16位定時器.
* 向下計數能得到精確的時間長度值.
*****************************************************/
void ConfigTimer1( void ){
PC_DDR &= ~( 1 << PC1 ); /* 配置爲輸入口 */
PC_CR1 = ( 1 << C11 ); /* 配置上拉電阻 */
TIM1_PSCRH = ( 1 << PSC11 ) + ( 1 << PSC10 );
TIM1_PSCRL = ( 1 << PSC07 ) + ( 1 << PSC06 )
+ ( 1 << PSC05 ) + ( 1 << PSC02 )
+ ( 1 << PSC01 ) + ( 1 << PSC00 );
/* 分頻率爲PSCR[15:0] + 1 = 1000 */
TIM1_CNTRH = 0x46;
TIM1_CNTRL = 0x50;
TIM1_ARRH = 0x46;
TIM1_ARRL = 0x50;
/*
18,000,000
CNTR = ------------ = 0x4650
1,000
*/
TIM1_CR2 = 0; /* CC1輸入管腳連到TIM1_CH1 */
TIM1_CCMR1 = ( 1 << CC1S00 ); /* 連接到TIM1_CH1引腳,無濾波,無分頻 */
/* 注:CC1S僅在通道關閉時(TIM1_CCER1寄存器的CC1E=0)纔是可寫的. */
TIM1_CCER1 = ( 1 << CC1P ) /* 下降沿有效 */
+ ( 1 << CC1E ); /* 捕獲使能 */
TIM1_SR1 &= ~( 1 << CC1IF ); /* 清除捕獲標誌 */
TIM1_SR2 &= ~( 1 << CC1OF ); /* 清除重複捕獲標誌 */
TIM1_IER = ( 1 << CC1IE ); /* 捕獲中斷使能 */
TIM1_CR1 = ( 1 << DIR ) /* 向下計數 */
+ ( 1 << CEN ); /* 使能計數 */
}
/*****************************************************
@Fn: CalculatePulseLen()
@Br: 計算脈衝的時間長度
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void CalculatePulseLen( void ){
ulong Temp;
uchar Buff[7];
if( uiTenor & TM1_CAP_FLAG )
{
if( uiCaptureT1[0] <= uiCaptureT1[1] )
{
uiCaptureT1[0] += PRELOAD_VALUE_1S;
}
Temp = uiCaptureT1[0] - uiCaptureT1[1]; /* 捕獲計數長度 */
/*
計算脈寬
脈衝時鐘 clk = 捕獲值 * 分頻倍率
= i * 1000
脈衝時鐘 11,995,575
t = ---------- = ------------ = 0.66642 s
系統時鐘 18,000,000
*/
Temp = Temp * 1000;
Temp = Temp / 18; /* 放大1,000,000倍 */
Buff[6] = Temp % 10;
Temp /= 10;
Buff[5] = Temp % 10;
Temp /= 10;
Buff[4] = Temp % 10;
Temp /= 10;
Buff[3] = Temp % 10;
Temp /= 10;
Buff[2] = Temp % 10;
Temp /= 10;
Buff[1] = Temp % 10;
Temp /= 10;
Buff[0] = Temp % 10;
memcpy( &ucCapBuff[0], &Buff[0], SEVEN_LEN );
uiTenor &= ~TM1_CAP_FLAG;
}
free( Buff );
}
suzhwt 發表於 2010-9-21 15:45
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/* Timer4, Timer6 */
/*****************************************************
@Fn: ConfigTimer4()
@Br: Timer4初始化爲定時器方式
@Pa: 無
@Rt: 無
@Sp: 計算CNT值的方法與其他處理器的不一樣.
Timer4, Timer6 是基本8位定時器.
*****************************************************/
void ConfigTimer4( void ){
TIM4_PSCR = ( 1 << PSC02 ) + ( 1 << PSC01 ) + ( 1 << PSC00 );
/* Configure TIM4 prescaler = 128 */
/* Fck_cnt = Fck_psc / 2 ^[2:0] */
TIM4_ARR = 0xFF; /* TIM4的自動裝載寄存器 */
TIM4_CNTR = 0xFF; /* TIM4的計數器 */
/*
18,000,000
CNTR = ------------ = 140,625
128
中斷一次的時間
t = 256 / 140,625 = 0.0018204 s
*/
TIM4_CR1 = ( 1 << ARPE ) + ( 1 << CEN ); /* 允許自動重裝載,使能計數器 */
TIM4_IER = ( 1 << UIE ); /* 允許更新中斷 */
}
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/* Timer2, Timer3, Timer5 */
/*****************************************************
@Fn: ConfigTimer2()
@Br: Timer2初始化爲定時器方式
@Pa: 無
@Rt: 無
@Sp: 計算CNT值的方法與其他處理器的不一樣.
Timer2,Timer3,Timer5 是通用16位定時器.
*****************************************************/
void ConfigTimer2( void ){
TIM2_PSCR = ( 1 << PSC03 ) + ( 1 << PSC01 );
/* Configure TIM2 prescaler = 1024 */
/* Fck_cnt = Fck_psc / 2 ^[3:0] */
TIM2_ARRH = 0x44; /* TIM2的自動裝載寄存器 */
TIM2_ARRL = 0xAA;
TIM2_CNTRH = 0x44; /* TIM2的計數器 */
TIM2_CNTRL = 0xAA;
/*
18,000,000
CNTR = ------------ = 0x44AA
1024
*/
TIM2_CR1 = ( 1 << ARPE ) + ( 1 << CEN ); /* 允許自動重裝載,使能計數器 */
TIM2_IER = ( 1 << UIE ); /* 允許更新中斷 */
}
suzhwt 發表於 2010-9-21 15:45
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigUART1()
@Br: 配置USART1
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigUART1( void ){
UART1_SR = ( 1 << RXNE ); /* 使能接收 */
UART1_CR1 = 0; /* 1個起始位,8個數據位, */
UART1_CR3 = 0; /* 1個停止位 */
UART1_CR4 = 0;
UART1_CR5 = 0;
/*
Fmaster 18,000,000
Baud rate = ------------ = ---------- = 7500 = 0x1D4C
UART_DIV 2400
UART_BRR1 = UART_DIV[11:4]
UART_BRR2 = UART_DIV[15:12] | UART_DIV[3:0]
*/
UART1_BRR2 = 0x1C;
UART1_BRR1 = 0xD4; /* 2400bps @ 18MHz,先寫BRR2再寫BRR1 */
UART1_CR2 = ( 1 << RIEN ) + ( 1 << TEN ) + ( 1 << REN );
/* 接收中斷使能, 發送與接收使能 */
}
/*****************************************************
@Fn: TransmitFrame()
@Br: 從UART1發送數據
@Pa: 緩衝指針及長度
@Rt: 無
@Sp: 無
*****************************************************/
void TransmitFrame( uchar *Buff, uchar Len ){
for( uchar i = 0; i < Len; i++ )
{
while(( UART1_SR & ( 1 << TXE )) == 0 );
UART1_DR = *Buff++;
_NOP();
}
}
suzhwt 發表於 2010-9-21 15:46
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*
對窗口看門狗的應用理解:
在一個程序線程中,如果在特定的時間內,操作沒有被完
成,則由該窗口看門狗實現復位,而不是傳統操作上的死機,
例如,
在由CPU對一個芯片進行讀數據的操作過程中,因硬件的
問題導致CPU在此操作中死循環而無法退出,那麼,可以由這個
WWDG設置一個時間級限,如果在此極限中若沒有將WWDG停止,
則復位發生.
*/
/*****************************************************
@Fn: ConfigWWDG()
@Br: WWDG初始化
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigWWDG( void ){
WWDG_WR = 0x7F;
WWDG_CR = ( uchar )(( 1 << WDGA ) + 0x7F );
WWDG_WR = 0x6F;
}
/*****************************************************
@Fn: RefreshWWDG()
@Br: 更新WWDG
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void RefreshWWDG( void ){
uchar Temp;
Temp = WWDG_CR & ~( 1 << WDGA );
if( Temp < WWDG_WR )
{
WWDG_CR = ( uchar )(( 1 << WDGA ) | 0x7F );
}
}
suzhwt 發表於 2010-9-21 15:46
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
#pragma vector = EXTI_A_VECT
__interrupt void PA_ISR( void ){
if(( PA_IDR & ( 1 << IDR6 )) == 0 )
{
uiTenor |= PA6_INT_FLAG;
}
}
#pragma vector = TM1CC_VECT
__interrupt void TIM1_CAPTURE_ISR( void ){
if( TIM1_SR1 & ( 1 << CC1IF ))
{
if( TIM1_CCER1 & ( 1 << CC1P )) /* 下降沿產生的中斷 */
{
uiCaptureT1[0] = ( TIM1_CCR1H << 8 );
uiCaptureT1[0] |= TIM1_CCR1L;
TIM1_CCER1 &= ~( 1 << CC1P ); /* 改爲上升沿捕獲 */
}
else /* 上升沿產生的中斷 */
{
uiCaptureT1[1] = ( TIM1_CCR1H << 8 );
uiCaptureT1[1] |= TIM1_CCR1L;
TIM1_CCER1 |= ( 1 << CC1P ); /* 改爲下降沿捕獲 */
uiTenor |= TM1_CAP_FLAG; /* 一段低電平時間捕獲 */
}
}
}
#pragma vector = TM2OV_VECT
__interrupt void TIM2_UPDATE_ISR( void ){
if( TIM2_SR1 & ( 1 << UIF ))
{
TIM2_SR1 &= ~( 0x01 );
uiTenor |= TIME2_FLAG;
}
}
#pragma vector = TM4OV_VECT
__interrupt void TIM4_UPDATE_ISR( void ){
if( TIM4_SR & ( 1 << UIF ))
{
TIM4_SR &= ~( 0x01 );
uiTenor |= TIME4_FLAG;
}
}
#pragma vector = UART1RX_VECT
__interrupt void UART1RX_ISR( void ){
ucBuff[ ucIndex++ ] = UART1_DR;
if( ucIndex >= 2 )
{
if( ucIndex >= ucBuff[1] )
{
ucIndex = 0;
uiTenor |= UART1_RX_FLAG;
}
}
}
#pragma vector = ADC_VECT
__interrupt void ADC10_ISR( void ){
ADC_CSR &= ~( 1 << EOC );
uiADC = ( ADC_DRH << 8 );
uiADC |= ADC_DRL;
}
#pragma vector = SPI_VECT
__interrupt void SPI_ISR( void ){
if( SPI_SR & ( 1 << SPI_RXNE ))
{
SPI_DR = SPI_DR;
}
}
suzhwt 發表於 2010-9-21 15:46
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
/* Author: EighthArmy @ July.2010 */
/*****************************************************
@Fn: ConfigCPU()
@Br: 配置處理器及外圍
@Pa: 無
@Rt: 無
@Sp: 無
*****************************************************/
void ConfigCPU( void ){
_DI();
ConfigClock();
ConfigGPIO();
ConfigInterrupt();
ConfigTimer1();
ConfigTimer2();
ConfigT3_PWM2();
ConfigTimer4();
ConfigADC10();
ConfigUART1();
InitialFlashReg();
//ConfigWWDG();
_EI();
}
suzhwt 發表於 2010-9-21 15:47
#include "ioSTM8S207S8.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Variables.h"
/* Author: EighthArmy @ July.2010 */
void main( void ){
uint i = 0;
ConfigCPU();
while( 1 )
{
if( uiTenor & TIME2_FLAG )
{
PG_ODR ^= 0x01;
PE_ODR ^= ( 1 << PE5 );
uiTenor &= ~TIME2_FLAG;
}
if( uiTenor & PA6_INT_FLAG )
{
PG_ODR ^= 0x02;
ucBuff[0] = 0x11;
ucBuff[1] = 0x22;
ucBuff[2] = 0x33;
ucBuff[3] = 0x44;
ucBuff[4] = 0x55;
ucBuff[5] = 0x66;
ucBuff[6] = 0x77;
ucBuff[7] = 0x88;
TransmitFrame( &ucBuff[0], 8 );
uiTenor &= ~PA6_INT_FLAG;
}
if( uiTenor & TIME4_FLAG )
{
i++;
if( i >= 100 )
{
PE_ODR ^= ( 1 << PE6 );
i = 0;
}
uiTenor &= ~TIME4_FLAG;
}
Comm1Events();
CalculatePulseLen();
//RefreshWWDG(); /* 清窗口看門狗,窗口看門狗在硬件復位 */
}
}
壓縮包中的SPI模塊包含主從通訊,可以實現主從SPI方式通訊。
相比之下,速度要比UART爽多了。
學STM8的朋友千萬不要錯過啊!!
這都是心血和經驗啊!