|
/*******************************************************************
串口1DMA接收不定長度數(shù)據(jù):利用串口1中斷,定時(shí)器0超時(shí)判定,很好地實(shí)現(xiàn)串口1DMA接收
不定長度數(shù)據(jù)到XARM, 并很好地實(shí)現(xiàn)接收完成后,原樣返回給PC,不受256字節(jié)限制,
1-N個(gè)字節(jié)隨意(但要在Dshow定義范圍內(nèi))。
問題是:UART1_DMA死活進(jìn)不了中斷 。按理說串口1DMA接收完定義的字節(jié)長度,進(jìn)中斷才是正招啊。
雖然下面的方案也很好地解決了問題,但心里總不舒服,哪位大神指點(diǎn)下啊。單片機(jī)STC8H8K64U.
*********************************************************************/
單片機(jī)源程序如下:
//#include "dma.h"
#include "STC8h.h"
#define u32 unsigned long
#define u16 unsigned int
#define u8 unsigned char
#define MAIN_Fosc 22118400UL
#define Baudrate1 115200UL // 波特率115200
#define Timer0_Reload (65536UL - (MAIN_Fosc /1000UL))
#define DMA_AMT_LEN 255 //0-255 最大定義范圍255。實(shí)際可連續(xù)發(fā)送N多個(gè)
bit B_1ms,TANG;
u16 Rx_cnt;
u8 RX1_TimeOut;
void GPIO_Config();
void UART1_Config(u8 brt);
void DMA_Config(void);
void Timer0_Init();
void DMA_RX(u8 g);
void DMA_TX();
void UartSendByte(u8 dat);
void UartSendStr(u8 *str);
u8 xdata Dshow[4096]={0};
void main(void)
{ u8 g=0; //用于累加多少個(gè)DMA_AMT_LEN數(shù)
GPIO_Config();
DMA_Config();
UART1_Config(1);
Timer0_Init();
B_1ms=0;TANG=0;Rx_cnt=0; RX1_TimeOut=0;
while (1)
{ if(TANG){g++; DMA_RX(g) ; Rx_cnt=0; TANG=0;}//就是這樣處理類似dma中斷的.郁悶。。??
if(B_1ms) //1ms 到
{ B_1ms = 0;
if(RX1_TimeOut > 0)
{ if(--RX1_TimeOut == 0) // 接收超時(shí)計(jì)數(shù)
{ DMA_UR1R_CR = 0x00; // 關(guān)閉 UART1_DMA
Dshow[g*(DMA_AMT_LEN+1)+Rx_cnt]='\0';
UartSendStr(Dshow);//發(fā)送到串口。當(dāng)然也可用DMA發(fā)送,但涉及到字節(jié)多少的處理,偷一個(gè)懶
g =0;Rx_cnt=0; TANG=0;
DMA_RX(0); //重新初始化
}
}
}
}
}
/*********************************************************
***********************************************************/
void DMA_RX(u8 g)
{ DMA_UR1R_CFG = 0x00; // 屏蔽串口1DMA接收中斷
DMA_UR1R_STA = 0x00; //關(guān)閉dma 清零串口1DMA接收完成中斷標(biāo)志、清零數(shù)據(jù)丟棄中斷標(biāo)志
DMA_UR1R_AMT = DMA_AMT_LEN; // 設(shè)置傳輸總字節(jié)數(shù)(低8位):n+1
DMA_UR1R_RXA = (u16)Dshow+ (DMA_AMT_LEN+1)*g ; // 設(shè)置傳輸數(shù)據(jù)的目標(biāo)地址,低8位
DMA_UR1R_CR = 0xa1;
}
/*********************************************************
***********************************************************/
void DMA_TX()
{ DMA_UR1T_CFG = 0x00; // 屏蔽串口1DMA接收中斷
DMA_UR1T_STA = 0x00; //關(guān)閉dma 清零串口1DMA發(fā)送完成中斷標(biāo)志、清零數(shù)據(jù)覆蓋中斷標(biāo)志
DMA_UR1T_AMT = DMA_AMT_LEN; // 設(shè)置傳輸總字節(jié)數(shù)(低8位):n+1
DMA_UR1T_TXA = (u16)Dshow; // 設(shè)置傳輸數(shù)據(jù)的源地址
}
/*********************************************************
***********************************************************/
void DMA_Config(void)
{ DMA_TX(); DMA_RX(0);
}
/*********************************************************
***********************************************************/
void UART1_int (void) interrupt 4
{ if(RI) // 接收完成標(biāo)志置1時(shí)
{ RI = 0; // 清零接收完成標(biāo)志
if(Rx_cnt == DMA_AMT_LEN) TANG = 1; //就是這樣處理類似dma中斷的.郁悶。???
else {Rx_cnt++; TANG = 0; }
RX1_TimeOut = 5; // 如果 5ms 沒收到新的數(shù)據(jù),判定一串?dāng)?shù)據(jù)接收完畢
}
if(TI) TI = 0; // 發(fā)送標(biāo)志置1時(shí)
}
/*********************************************************
串口1初始化 (可用定時(shí)器1/2)
***********************************************************/
void UART1_Config(u8 brt)
{ u16 dat ;
dat = 65536UL- (MAIN_Fosc/4)/ Baudrate1;
if (brt==2)
{ AUXR|=0X01;
AUXR &=~(1<<4);
AUXR &=~(1<<3);
AUXR |=(1<<2);
T2H=(u8)(dat/256);
T2L=(u8)(dat%256);
IE2&= ~(1<<2);
AUXR |=(1<<4);
}
else
{ TR1=0;
AUXR&=~0X01;
AUXR|=(1<<6);
TMOD&=~(1<<6);
TMOD&=~0X30;
TH1=(u8)(dat/256);
TL1=(u8)(dat%256);
ET1=0;
INTCLKO&=0X02;
TR1=1;
}
SCON=(SCON&0X3F)|0X40;
//PS=1;
ES=1;
REN=1;
P_SW1&=0X3F;
P_SW1|=0X00;
}
/*********************************************************
***********************************************************/
void timer0(void) interrupt 1
{ B_1ms = 1; } // 1毫秒標(biāo)志
/****************************************************
***************************************************/
void Timer0_Init(void) //1毫秒@22.1184MHz
{ AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
TMOD &= 0xF0; //設(shè)置定時(shí)器模式
TMOD |= 0x01; //設(shè)置定時(shí)器模式
TL0 = 0x9A; //設(shè)置定時(shí)初始值
TH0 = 0xA9; //設(shè)置定時(shí)初始值
TF0 = 0; //清除TF0標(biāo)志
ET0=1;
TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
EA=1;
}
/***************************************************
***************************************************/
void GPIO_Config() //GPIO設(shè)置
{ P_SW2|=0X80;
P0M1 = 0x00;P0M0 = 0x00;
P1M1 = 0x00;P1M0 = 0x00;
P2M1 = 0x00;P2M0 = 0x00;
P3M1 = 0x00;P3M0 = 0x00;
P4M1 = 0x00;P4M0 = 0x00;
P5M1 = 0x00;P5M0 = 0x00;
}
/************************************************************
************************************************************/
void UartSendByte(u8 dat)
{ bit m=0;
if (ES){ES= 0;m=1;}
SBUF = dat;
while(TI == 0);
TI = 0;
ES= m; ;
}
/*********************************************************
***********************************************************/
void UartSendStr(u8 *str)
{ bit m=0;
if (ES){ES= 0;m=1;}
while(*str)
{ UartSendByte(*str);
str++;
} ES= m;
}
/***********************************************************
************************************************************
void UART1_DMAerrupt() interrupt 13 // 串口DMA中斷號(hào)大于31,借用13號(hào)保留中斷中轉(zhuǎn)
{ P46=0; // 詳情參照布丁橘長-STC32系列視頻第36期,或STC32手冊第5.9章節(jié)
if (DMA_UR1T_STA & 0x01) // 發(fā)送完成中斷標(biāo)志為1時(shí)
{
DMA_UR1T_STA &= ~0x01; // 清零發(fā)送完成中斷標(biāo)志
DMATxFlag = 1; // 發(fā)送完成標(biāo)志置1
}
if (DMA_UR1T_STA & 0x04) // 數(shù)據(jù)覆蓋中斷標(biāo)志為1時(shí)
{
DMA_UR1T_STA &= ~0x04; // 清零數(shù)據(jù)覆蓋中斷標(biāo)志
}
if (DMA_UR1R_STA & 0x01) // 接收完成中斷標(biāo)志為1時(shí)
{
DMA_UR1R_STA &= ~0x01; // 清零接收完成中斷標(biāo)志
DMARxFlag = 1; // 接收完成標(biāo)志置1
}
if (DMA_UR1R_STA & 0x02) // 數(shù)據(jù)丟棄中斷標(biāo)志為1時(shí)
{
DMA_UR1R_STA &= ~0x02; // 清零數(shù)據(jù)丟棄中斷標(biāo)志
}
}
/***********************************************************
************************************************************
if((DMATxFlag) && (DMARxFlag)) // 當(dāng)發(fā)送和接收完成標(biāo)志均為1時(shí),表示空閑
{ Rx_cnt = 0; P45=0; // 清零接收計(jì)數(shù)
RX1_TimeOut = 0; // 清零接收超時(shí)計(jì)數(shù)
DMATxFlag = 0; // 清零發(fā)送完成標(biāo)志
DMA_UR1R_STA = 0x00;
DMA_UR1T_AMT=Rx_cnt; //設(shè)置UART1傳輸總字節(jié)數(shù):n+1
DMA_UR1T_TXA=Dshow; //設(shè)置UART1 DMA發(fā)送源地址
DMA_UR1T_CR = 0xc0; // bit7 1:使能 UART1_DMA, bit6 1:開始 UART1_DMA 自動(dòng)發(fā)送
DMARxFlag = 0; // 清零接收完成標(biāo)志
DMA_UR1R_CR = 0xa1; // bit7 1:使能 UART1_DMA, bit5 1:開始 UART1_DMA 自動(dòng)接收, bit0 1:清除 FIFO
}
**********************************************************/
|
|