小弟最近在學習xmega的晶片,遇到許多困難
望大大們海量能教教我~~~~
小弟我基本架構已經完成了
基本上電腦可以接受到單晶片傳出來的資料
但是我設置傳出"33" 電腦串口助手顯示 80 80 00
然後電腦端的串口助手輸出"11"(希望燈1.3.5.7亮)時,也是跳到else(led燈全亮)
程式如下:
================程式分隔線====================
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
//=======函數定義========
void USART_INIT (void);
uint8_t usart_rx (USART_t* _usart);
void usart_tx (USART_t* _usart,uint8_t data);
//由pc傳送,單晶片接收指令
#define LED1357_ON 11
#define LED2468_ON 22
//PORT
#define USART_MAIN USARTE0
int main(void)
{
PORTJ_DIR=0xFF; //led enable
PORTJ_OUTSET=0xff; //led 設1 燈滅
USART_INIT();
sei(); //全局中斷開啟
while(1)
{
PORTJ_OUTSET = 0Xff; //led 設1 燈滅
usart_tx(&USART_MAIN,33); //向pc端送出訊號
_delay_ms(200) ;
}
}
//=========初始化usart=============
void USART_INIT (void)
{
PORTE.DIRSET = PIN3_bm; //TX 輸出
PORTE.DIRCLR = PIN2_bm; //RX 輸入
//控制模式選擇= 異步 | 基偶校驗關閉 | 停止位1位 | 長度8bit
USARTE0.CTRLC= 0X03 ;
USARTE0.BAUDCTRLA = 103; //波特率 9600
USARTE0.BAUDCTRLB = 0;
USARTE0.CTRLB= USART_RXEN_bm | USART_TXEN_bm ; //啟用接收.傳送.8bit
PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm;
USARTE0.CTRLA= USART_RXCINTLVL_HI_gc; //接收中斷"高" 當單晶片的STATUS暫存器的RXCID被置位時,觸發中斷
}
//=========接收中斷========
ISR(USARTE0_RXC_vect)
{
switch(usart_rx(&USART_MAIN))
{
case LED1357_ON:
PORTJ_OUTCLR = 0X55;
_delay_ms(100);
break;
case LED2468_ON:
PORTJ_OUTCLR = 0XAA;
_delay_ms(100);
break;
default: //上述皆無
PORTJ_OUTCLR = 0Xff;
_delay_ms(100);
break;
}
}
//=======中斷後讀取DATA=============
uint8_t usart_rx(USART_t* _usart) // uint8_t為0~255超過歸0重來 (0x00~0xFF)
{
while(((_usart->STATUS)& USART_RXCIF_bm)==0); //_usart的成員STATUS讀 "單晶片USART_RXCIF_bm地方" 的值,讀到0時 表示有接收中斷
return (_usart->DATA); //回傳 _usart存取他的成員DATA(數據寄存器)
}
//===========發送中斷=============
void usart_tx( USART_t* _usart , uint8_t data )
{
while (((_usart->STATUS) &USART_DREIF_bm)==0); //_usart的成員STATUS讀 "單晶片USART_DREIF_bm地方" 的值,讀到0時 表示有data
_usart->DATA=data; //_usart存取他的成員DATA(數據寄存器) =data
}
=====================程式結束===============
失敗後 小弟第一直覺就是時間寫錯,於是改用外部晶振來控制一樣失敗
情況與上面一致
以下是小弟寫的由外部晶振控制系統時間
============程式分隔線==================================
#ifndef F_CPU
#define F_CPU 20000000UL
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//=======函數定義========
void USART_INIT (void);
void Initial_colck_seting(void);
uint8_t usart_rx (USART_t* _usart);
void usart_tx (USART_t* _usart,uint8_t data);
//SWITCH
#define LED1357_ON 11
#define LED2468_ON 22
//PORT
#define USART_MAIN USARTE0
int main(void)
{
PORTJ_DIR=0xFF; //led enable
PORTJ_OUTSET=0xff; //led 設1 燈滅
Initial_colck_seting();
USART_INIT();
sei(); //全局中斷開啟
while(1)
{
PORTJ_OUTSET = 0Xff; //led 設1 燈滅
usart_tx(&USART_MAIN,33); //向pc端送出訊號
_delay_ms(200) ;
}
}
//=========初始化usart=============
void USART_INIT (void)
{
PORTE.DIRSET = PIN3_bm; //TX 輸出
PORTE.DIRCLR = PIN2_bm; //RX 輸入
//控制模式選擇= 異步 | 基偶校驗關閉 | 停止位1位 | 長度8bit
USARTE0.CTRLC= 0X03 ;
USARTE0.BAUDCTRLA = 129; //波特率 9600
USARTE0.BAUDCTRLB = 0;
USARTE0.CTRLB= USART_RXEN_bm | USART_TXEN_bm ; //啟用接收.傳送.8bit
PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm;
USARTE0.CTRLA= USART_RXCINTLVL_HI_gc; //接收中斷"高" 當單晶片的STATUS暫存器的RXCID被置位時,觸發中斷
}
//=========接收中斷========
ISR(USARTE0_RXC_vect)
{
switch(usart_rx(&USART_MAIN))
{
case LED1357_ON:
PORTJ_OUTCLR = 0X55;
_delay_ms(100);
break;
case LED2468_ON:
PORTJ_OUTCLR = 0XAA;
_delay_ms(100);
break;
default: //上述皆無
PORTJ_OUTCLR = 0Xff;
_delay_ms(100);
break;
}
}
//=======中斷後讀取DATA=============
uint8_t usart_rx(USART_t* _usa // uint8_t為0~255超過歸0重來 (0x00~0xFF)
{
while(((_usart->STATUS)& USART_RXCIF_bm)==0); //_usart的成員STATUS讀 "單晶片USART_RXCIF_bm地方" 的值,讀到0時 表示有接收中斷
return (_usart->DATA); //回傳 _usart存取他的成員DATA(數據寄存器)
}
//===========發送中斷=============
void usart_tx( USART_t* _usart , uint8_t data )
{
while (((_usart->STATUS) &USART_DREIF_bm)==0); //_usart的成員STATUS讀 "單晶片USART_DREIF_bm地方" 的值,讀到0時 表示有data
_usart->DATA=data; //_usart存取他的成員DATA(數據寄存器) =data
}
//==============時鐘設定==================
void Initial_colck_seting(void) //PLL=倍頻 XOSC=晶體振盪器
{
/* 振盪源與振盪頻率設定 使用外部振盪器4MHZ + 5倍 PLL 使系統振盪頻率為20MHZ*/
//系統時鐘與時鐘選項
CCP = CCP_IOREG_gc; // 配置更改保護註冊 Protected IO register Configuration Change Protection Register
CLK.CTRL = CLK_SCLKSEL_XOSC_gc; //系統時鐘選項=外部震盪
CLK.PSCTRL = 0; //分頻 0=不分頻
//振盪器
OSC.CTRL = OSC_PLLEN_bm | OSC_XOSCEN_bm; //振盪器 = 倍頻 | 外部晶振
OSC.XOSCCTRL = OSC_XOSCSEL_XTAL_1KCLK_gc | OSC_FRQRANGE_2TO9_gc;// 外部振盪器= 選擇和啟動時間 | 震盪頻率選擇 2TO9
// 2TO9==>2MHz~9MHz 適用電容C1.C2=15pF
OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC4_bm ; //倍頻設定=外部晶振 | 4倍
_delay_ms(100);
}