㈠ stc單片機容易跑飛
stc晶元本身不穩定,抗干擾能力極差!stc單片機不能用於工控。跑飛原因有幾個
1 看看有沒有堆棧溢出
2程序儲存段有沒有越界。
3電源電壓不穩,加大電源濾波電容加一個5伏穩壓二極體
4io口是否受到外界干擾最好加光耦隔離
5如果自動復位,復位引腳不用時接上拉電阻到5伏,同時引腳加個對地電容
6板子地線要接地
㈡ 單片機波
#include<reg52.h> //包含頭文件
#include<intrins.h>
#define uchar unsigned char //宏定義
#define uint unsigned int
sbit s1=P3^5; //定義按鍵的介面
sbit s2=P3^6;
sbit s3=P3^7;
sbit s4=P3^4;
sbit s5=P2^3;
sbit led0=P3^0; //定義四個LED,分別表示不同的波形
sbit led1=P3^1;
sbit led2=P3^2;
sbit led3=P3^3;
sbit lcdrs=P2^7; //液晶控制引腳,還有一個控制腳是RW,因為我們只需要向液晶里寫數據系那是就好了,所以,我們直接將RW引腳接地
sbit lcden=P2^6;
char num,boxing,u; //定義全局變數
uchar pinlv=100,bujin=1,bujin1=1; //頻率初始值是10Hz,步進值默認是0.1,顯示步進值變數
uchar code table[]="0123456789"; //定義顯示的數組
uchar code table1[]="Fout= Wave form:"; //初始化顯示字元
unsigned int m,pwm=50; //定義變數 m
int a,b,h,num1; //定義全局變數
//自定義字元
uchar code zifu[]={ //此數組內數據為液晶上顯示波形符號的自定義字元
0x0e,0x11,0x11,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x11,0x11,0x0e,0x00, //正弦波 0 1
0x00,0x07,0x04,0x04,0x04,0x04,0x1c,0x00,
0x00,0x1c,0x04,0x04,0x04,0x04,0x07,0x00, //矩形波 2 3
0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00,
0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00, //三角波 4 5
0x00,0x01,0x03,0x05,0x09,0x11,0x00,0x00, //鋸齒波 6
};
uchar code sin[64]={ //此數組內的數據為,da輸出對應電壓值對應的數字量,0是0V,255是5V
135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128
}; //正弦波取碼
uchar code juxing[64]={ //一個周期是采樣64個點, 所以數組內是64個數據
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
}; //矩形波取碼
uchar code sanjiao[64]={
0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
}; //三角波取碼
uchar code juchi[64]={
0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,
146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255
}; //鋸齒波取碼
void delay(uint xms) //延時函數
{
int a,b;
for(a=xms;a>0;a--)
for(b=110;b>0;b--);
}
void write_com(uchar com) //寫命令函數
{
lcdrs=0;
P0=com;
delay(1);
lcden=0;
delay(1);
lcden=1;
}
void write_date(uchar date) //寫數據函數
{
lcdrs=0;
P0=date;
delay(1);
lcden=0;
delay(1);
lcden=1;
}
//自定義字元集
void Lcd_ram()
{
uint i,j,k=0,temp=0x04;
for(i=0;i<7;i++)
{
for(j=0;j<8;j++)
{
write_com(temp+j);
write_date(zifu[k]);
k++;
}
temp=temp+8;
}
}
void init_lcd() //初始化函數
{
uchar i;
lcden=0; //默認開始狀態為關使能端,見時序圖
Lcd_ram();
write_com(0x01); //顯示清屏,將上次的內容清除,默認為0x01.
write_com(0x0f);
write_com(0x38); //顯示模式設置,默認為0x38,不用變。
write_com(0x0c); //顯示功能設置0x0f為開顯示,顯示游標,游標閃爍;0x0c為開顯示,不顯游標,游標不閃
write_com(0x06); //設置游標狀態默認0x06,為讀一個字元游標加1.
write_com(0x80); //設置初始化數據指針,是在讀指令的操作里進行的
for(i=10;i<20;i++) //顯示初始化
{
write_date(table1[i]); //顯示第一行字元
}
write_com(0x80+40); //選擇第二行
for(i=0;i<9;i++)
{
write_date(table1[i]); //顯示第二行字元
}
write_com(0x80+10); //選擇第一行第十個位置
write_date(0);
write_date(1);
write_date(0);
write_date(1);
write_date(0);
write_date(1); //顯示自定義的波形圖案
write_com(0x80+40+9); //選擇第二行第九個位置
write_date(' ');
write_date('1');
write_date('0');
write_date('.');
write_date('0');
write_date('H');
write_date('z'); //顯示初始的頻率值
}
void initclock() //定時器初始化函數
{
TMOD=0x01; //定時器的工作方式
TH0=a;
TL0=b; //定時器賦初值
EA=1; //打開中斷總開關
ET0=1; //打開定時器允許中斷開關
TR0=1; //打開定時器定時開關
}
void display() //顯示函數
{
uchar qian,,shi,ge; //定義變數用於顯示
qian=pinlv/1000; //將頻率值拆成一位的數據,將數據除以1000,得到的商是一位數,賦值給qian
=pinlv%1000/100; //將頻率除以1000的余數再除以100就得到了頻率的百位,賦值給
shi=pinlv%1000%100/10; //同上,得到頻率的十位
ge=pinlv%1000/100%10;
write_com(0x80+40+9); //選中第二行第九個位置
if(qian==0) //千位如果為0
write_date(' '); //不顯示
else //千位不為0
write_date(table[qian]); //正常顯示千位
if(qian==0&&==0) //千位和百位都為0
write_date(' '); //百位不顯示
else //不都為0
write_date(table[]); //百位正常顯示
write_date(table[shi]); //顯示十位數
write_date('.'); //顯示小數點
write_date(table[ge]); //顯示個位
write_date('H'); //顯示頻率的單位Hz
write_date('z');
if(boxing==0) //判斷波形為正弦波
{
write_com(0x80+10); //選中一行頻率圖案位置
write_date(0); //顯示正弦波圖案
write_date(1);
write_date(0);
write_date(1);
write_date(0);
write_date(1);
led3=1;
led0=0; //點亮正弦波指示燈
}
if(boxing==1) //注釋同上
{
write_com(0x80+10);
write_date(2);
write_date(3);
write_date(2);
write_date(3);
write_date(2);
write_date(3);
led0=1;
led1=0;
}
if(boxing==2)
{
write_com(0x80+10);
write_date(4);
write_date(5);
write_date(4);
write_date(5);
write_date(4);
write_date(5);
led1=1;
led2=0;
}
if(boxing==3)
{
write_com(0x80+10);
write_date(6);
write_date(6);
write_date(6);
write_date(6);
write_date(6);
write_date(6);
led2=1;
led3=0;
}
}
void keyscan() //頻率調節鍵盤檢測函數
{
if(s1==0) //加按鍵是否按下
{
EA=0; //關閉中斷
while(!s1); //按鍵松開
pinlv+=bujin; //頻率以步進值加
if(pinlv>1000) //最大加到100Hz
{
pinlv=100; //100Hz
}
display(); //顯示函數
m=65536-(15000/pinlv);//計算頻率
/*頻率值最小是10Hz,pinlv的值是100(因為要顯示小數點後一位),150000/100=1500,這個1500就是定時器需要計時的,單位是us,65536-1500得到的是定時器的初值,
先不管初值,先看定時時間,1500us,一個波形的周期是由64個定時組成的,所以,一個波形周期就是64*1500us=96000,也就是96ms,約等
於100ms,也就是10Hz的頻率*/
a=m/256; //將定時器的初值賦值給變數
b=m%256;
EA=1; //打開中斷總開關
}
if(s2==0) //減按鍵按下
{
EA=0;
while(!s2);
pinlv-=bujin; //頻率以步進值減
if(pinlv<100)
{
pinlv=100;
}
display();
m=65536-(15000/pinlv);
a=m/256;
b=m%256;
EA=1;
}
if(s3==0) //波形切換按鍵
{
EA=0;
while(!s3);
boxing++; //波形切換
if(boxing>=4) //4種波形
{
boxing=0;
}
display();
EA=1;
}
if(s5==0) //PWM切換按鍵
{
EA=0;
while(!s5);
pwm+=10;
if(pwm>90)
{
pwm=10;
}
// display();
EA=1;
}
}
void bujindisplay() //步進值設置界面顯示程序
{
uint ,shi,ge; //定義步進值 百十個位
=bujin1/100; //將步進值除以100得到百位,也就是頻率值的十位,因為有一個小數位
shi=bujin1%100/10; //將步進值除以100的余數除以十得到十位
ge=bujin1%100%10; //取餘10後得到個位,也就是頻率步進值的小數點後一位
write_com(0x80+11); //選中液晶第一行第十一列
if(==0) //百位是否為0
write_date(' '); //百位不顯示
else //百位不為0
write_date(table[]); //顯示百位數據
write_date(table[shi]); //顯示十位數據
write_date('.'); //顯示小數點
write_date(table[ge]); //顯示個位,也就是小數點後一位
}
void bujinjiance() //步進值設置鍵盤程序
{
if(s4==0) //步進設置按鍵按下
{
delay(5); //延時去抖
if(s4==0) //再次判斷按鍵
{
while(!s4); //按鍵釋放,按鍵松開才繼續向下執行
h++; //變數加
if(h==1) //進入設置狀態時
{
write_com(0x01); //清屏
write_com(0x80); //初始化顯示步進設置界面
write_date('S');delay(1); //step value
write_date('t');delay(1);
write_date('e');delay(1);
write_date('p');delay(1);
write_date(' ');delay(1);
write_date('v');delay(1);
write_date('a');delay(1);
write_date('l');delay(1);
write_date('u');delay(1);
write_date('e');delay(1);
write_date(':');delay(1);
bujin1=bujin; //步進值賦值給臨時變數
bujindisplay(); //顯示步進值
}
if(h==2) //退出設置
{
h=0; //清零
bujin=bujin1; //設置好的臨時步進值賦值給步進變數
init_lcd(); //初始化液晶顯示
initclock(); //定時器初始化
display(); //調用顯示程序
}
}
}
if(h==1) //設置步進值時
{
if(s1==0) //加按鍵按下
{
delay(5); //延時去抖
if(s1==0) //再次判斷
{
while(!s1); //按鍵釋放
bujin1++; //步進值加1
if(bujin1>=101) //步進值最大100,也就是10.0Hz
{
bujin1=1; //超過最大值就恢復到0.1Hz
}
bujindisplay(); //步進顯示
}
}
if(s2==0) //減按鍵,注釋同上
{
delay(5);
if(s2==0)
{
while(!s2);
bujin1--; //步進減
if(bujin1<=0)
{
bujin1=100;
}
bujindisplay();
}
}
}
}
void main() //主函數
{
init_lcd(); //調用初始化程序
m=65536-(15000/pinlv); //定時器初值
a=m/256;
b=m%256;
initclock(); //定時器初始化
led0=0; //點亮第一個波形指示燈
while(1) //進入while循環,括弧內為1,一直成立,所以也叫死循環,程序不會跳出,一直在內執行
{
if(h==0) //正常模式不是步進調節
{
keyscan(); //掃描按鍵
// display();
}
bujinjiance(); //掃描步進調節程序
switch(boxing) //選擇波形
{
case 0 : P1=sin[u]; break; //正弦波
case 1 : //矩形波
if(u<pwm*64/100)P1=255;
else
P1=0;
break;
case 2 : P1=sanjiao[u]; break; //三角波
case 3 : P1=juchi[u]; break; //鋸齒波
}
}
}
void T0_time()interrupt 1 //定時器
{
TH0=a;
TL0=b;
u++; //變數加
if(u>=64) //一個周期采樣64個點, 所以加到64就清零
u=0; //u清零
//根據不同的初值,定時器定時時間不同,達到不同頻率的目的
}
㈢ 51單片機串口發送u32丟數量
熱門頻道
首頁
博客
研修院
VIP
APP
問答
下載
社區
推薦頻道
活動
招聘
專題
打開CSDN APP
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
單片機
打開APP
C51單片機串口丟包的幾種情況分析! 轉載
2021-03-22 11:29:28
3點贊
嵌入式資訊精選
碼齡敗租5年
關注
今天來總結一下C51單片機串口驅動層丟包的幾種情況.
---C51單片機串攔枯衫口收發數據的原理---
1、串口驅動模塊組成
(1)串口數據收發器,串口收發數據時,底層執行實際收發動作的硬體單元;
(2) 串口相關寄存器,
SBUF:串口數據寄存器,當有數據收或發時,用來裝載收或發的數據,實際底層是分開收和發兩個不同寄存器的,用戶(程序員)只用SBUF就可以了;
RI:串口接收中斷標志,告訴CPU現在串口收到數據了
TI:串口發簡腔送中斷標志,告訴CPU現在串口有數據要發了;
TI和RI都是系統產生用戶軟體清零的。
(3)串口中斷服務函數;串口收數據和發數據的中斷是一個,收和發在同一個中斷服務函數進行,在RI為1時把寄存器SBUF里的數據拷貝到用戶緩存里,在TI為1 時,把用戶要發的數據裝載到SBUF里。
2、收數據過程
(1)對端串口發送器發了1byte數據
(2) 串口接收器收到1byte數據,存到SBUF寄存器,並把寄存器中RI位置1
(3)系統產生一個中斷,CPU內核輪詢發現RI為1是串口中斷,從用戶程序跳轉至串口中斷服務函數
(4)串口中斷服務函數中,把SBUF寄存器中的這1byte數據拷貝至用戶緩存
收數據過程是1byte產生一個中斷,也就是說數據是1byte 1byte收的。
數據流向過程如下圖:
3、發數據過程
(1)用戶把TI置1
(2) 系統產生中斷,內核輪詢到TI為1,跳轉至串口中斷服務函數
(3) 用戶把1byte要發的數據裝載至SBUF
(4)硬體發送器發送數據,發送完成自動把TI置1
(5)系統產生中斷,重復(2)~(4)
(6) 當用戶不再往SBUF裝數據時,發送數據過程結束
發數據也是1byte 1byte發,每1byte先產生中斷再裝載數據。
數據流向過程如下圖:
---串口丟包總結---
說明下,這是無操作系統的單片機程序。
我 = 串口硬體收發器+串口軟體中斷服務函數+串口相關寄存器。
用戶 = 應用程序
1、我的硬體收發器在收發數據,用戶把系統總中斷關了
先說收數據的情況,系統中斷被用戶關了,我的硬體部分還是能收數據的,我仍然會把RI置1,但是現在總中斷關了,就不會產生中斷了,不會去調起我的軟體中斷服務函數了,那這樣就會造成我放到SBUF里的數據還沒有傳給用戶,如果關中斷期間,我又收到了新的1byte數據,我就會把新的數據放到SBUF里,覆蓋了老的數據了。
這樣老的那1byte數據就丟掉了。
舉例:串口正在收數據時,用戶要寫一些掉電記憶的參數到Flash,操作Flash會關總中斷,此時如果串口在收數據可能會丟包。
解決:關總中斷之前判斷一下串口是不是在忙,串口無數據收到連續累計一段時間才認為閑。
發數據的情況會不會有問題?如果我的硬體在發數據,用戶把總中斷關了,我發完這1byte數據仍然會把TI置1,但是此時不會產生中斷,不會再進入我的軟體中斷服務函數繼續發數據,等中斷恢復了,CPU會馬上進入我的中斷服務函數,又會繼續發數據,所以發數據過程關總中斷不會造成發數據丟包。
2、有人在中斷服務函數里待太久,耽誤我的軟體收數據
我的硬體收到了數據,我把他放到了SBUF里,同時也置起了RI標志位,但不巧,這時候CPU在另一個中斷服務函數里在執行代碼,更不巧,這個中斷服務函數很長,有很多代碼要執行,要很久很久!
這不就誤事了嗎,CPU還沒從那個中斷服務函數出來,我的硬體又收到了新的1byte數據,我又把他裝到了SBUF里,置起了RI,老的那1byte數據還在SBUF,沒傳給用戶緩存呢,新的把他覆蓋掉了。
舉例:某MCU LED驅動用調光模式(即可調亮度模式),由於其中斷服務函數太長,造成串口收數據丟包
解決:設置串口中斷優先順序高於LED中斷優先順序,C51中高優先順序中斷可以搶斷低優先順序中斷,這樣串口就不會丟包了。
3、大量數據又收又發,我的軟體部分不夠聰明,忙不過來了
同時有數據在收和發,我也是能應付的,因為咱是全雙工的啊,收數據和發數據可以同時進行,是不同的硬體單元;此時RI和TI都會被我置成1,系統會進去中斷服務函數,但系統是不知道這次進去是TI還是RI事件的,只管其中一個為1就進去了。
我的軟體中斷服務函數進去一次可以把收和發的數據都處理了,出來後就不會再次進中斷服務函數了,
如果程序員把我的軟體寫成進一次中斷服務函數只處理RI或者TI一個事件,那就效率很低啊!數據很多時極有可能會丟包!
比如如果優先處理TI事件,下次再進來想處理RI了但此時TI事件又有了,RI事件就又沒處理到了。
如果優先處理RI事件,收到的數據不會丟,但是下次進來RI事件又產生了,又要處理RI事件,想發的數據一直沒機會發。
所以,串口中斷服務函數里要能同時處理RI 和TI 中斷事件,下圖中的else if 應改成if。
又如果,串口中斷服務函數裡面太長,前一次還沒處理完,新的中斷又到了,就會自己耽誤自己。
4、當前數據還沒發完,用戶又把新數據裝到我的SBUF中
我的硬體在發數據,此時TI已經被用戶程序清0了,
如果程序員邏輯不夠清晰,馬上又要發一包新數據,把TI置1 了,那麼CPU會馬上進入中斷服務函數,中斷服務函數馬上會把新的1byte 數據裝到我的SBUF里,我剛剛正在發的那1byte 數據還沒發完就被新數據覆蓋弄丟了。
解決:程序串口驅動層介面發數據前,先判斷當前是否處於發送數據過程中,若正在發送過程中,不用再將TI置1.
5、 我們這里總中斷關了,對方還發數據給我
總中斷關了,對方給我發數據,我的硬體還是能收到數據的,我也會把RI置1,但是此時就不會產生中斷,不會進入中斷服務函數了,如果對方馬上又給我發了新的1byte數據,用戶這時還是沒有把總中斷打開,剛剛那1byte數據還在SBUF中會被新來的數據覆蓋,用戶沒取走丟掉了。
解決:對方增加重發邏輯。
6、我硬體能力不夠,收發速度跟不上
用戶竟然選擇了系統時鍾才2M,我的波特率卻被設置成了115200這么大,
此時我的波特率發生器產生的波特率已經不能達到115200了,數據還是能1byte 1byte的發出去,只是就是發出去的數據電平的長度可能不對了,
標准串口每1byte數據 = 1bit起始位+ 8bit數據位+奇偶校驗位(1或1.5或2或無)+停止位(1bit),起始電平是低電平,無數據時是高電平。
波特率115200即115200 bit/s,波特率決定了電平0/1的長度,波特率確定了1bit電平的長度就確定了,波特率越大,長度越短。
如果電平長度不對了,對方串口接收器收到這一串電平後經過解析可能就不認為這是一包正確的數據來了,因此丟棄了(底層電路具體是怎麼樣不是很了解)。
1.外媒談英偉達-Arm並購案~
2.這里聚焦了全球嵌入式技術風景~
3.航天器、導彈喜歡用單片機?
4.工程師的硬核單片機編程思想~
5.嵌入式開發需要架構設計嗎?
6.【技術轉管理必備】嵌入式產品的研發流程
免責聲明:本文系網路轉載,版權歸原作者所有。如涉及作品版權問題,請與我們聯系,我們將根據您提供的版權證明材料確認版權並支付稿酬或者刪除內容。
文章知識點與官方知識檔案匹配
Java技能樹首頁概覽
87773 人正在系統學習中
打開CSDN,閱讀體驗更佳
串口丟包受什麼影響_總結一下曾經在串口方面犯的錯誤_weixin_39772652的...
串口接收端丟包嚴重時,如果不是因為明顯錯誤導致,一般都是由於數據傳輸速度快,主控處理不過來造成的,想辦法降低傳輸速度: (1)波特率: 最直接的方法就是降低波特率,我做過一個小實驗,用幀序號來判斷丟包情況,當丟包時亮起一盞燈,波特率...
Qt串口QSerialPort丟包問題,QSerialPort和QTimer定時器中斷沖突的解決...
1.利用QTimer進行圖像顯示,每隔一定時間刷新圖像 2.另一個線程同步讀取串口中IMU的數據 3.測量時間可知,讀取串口的線程在QTimer中斷時耗時會大幅增加 還有一個問題是QSerialPort丟包。Qt5加入了QSerialPort的串口類,但經常會丟包,例如:...
51系列單片機串口緩存
51系列單片機串口緩存,已測試的單片機包括AT89C55WD、NXP89C669、STC11F60XE; buffer具有互鎖機制,完美解決串口中斷丟失數據,緩存數據等問題
填一個STC15F單片機串口通信的坑
STC單片機串口通信填坑最近在做個串口通信的案子,雙方約定通信波特率為115200,進行過程中,雙方按照50Hz頻率發送數據包,包長最大30byte,接收時,為了不掉數據,我使用了環形FIFO,數據在串口中斷寫入,主程序通過讀取FIFO來提取數據,使用FIFO讀取數據時,為了保證數據可靠性,不能同時寫入,所以需要將串口中斷暫時關閉語句內容大致如下:{ES=0;語句1,語句2,ES=1}語句1和語句...
繼續訪問
Qt串口處理數據丟包問題_少安的磚廠的博客_qt 串口數據...
1.將串口類的readyRead信號連接到自定義的readData函數 connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData); 2.readData函數:數據包格式為2位開始位,這個函數中使用有限狀態機方法實現開始位判斷。
linux嵌入式串口通信丟包,IMX6 Linux系統下串口丟包錯包問題研究_墨菲...
無硬體流控串口丟包發生時機點: 處理當前串口中斷的CPU被其他中斷搶占 IMX6系列CPU,默認的IRQ中斷優先順序,是中斷號小的,優先順序高,可以優先處理。所以,如果當串口的數據已經來臨,FIFO接受到的數據,已經達到觸發中斷的閾值,此時應該是產生串口...
51單片機串口列印亂碼的解決方法
我使用的是stc的89c52rc型號,晶振是12m。是因為買的最小系統就是這個頻率。使用波特率位9600,將TL、TH都設置成0xfd後不管是英文還是中文的都是亂碼。
QT串口與51單片機通信
QT串口與51單片機通信 qt與單片機的串口通信 qt與單片機的串口通信 qt與單片機的串口通信
STC51單片機串口下載軟體
STC51單片機的高級版本燒錄器,包含串口開發助手功能,可選擇發送多位元組數據
串口通信丟包分析
RS232/RS422/RS485 非同步通信通常使用一個UART 來發送和接受數據,用UART 晶元來控制串口的傳輸。UART晶元內部有一個FIFO緩沖區,用於存儲軟體驅動程序的輸入數據。 FIFO的大小為1、16、64或128個位元組,具體取決於UART類型。 FIFO用於通過緩沖數據來提高兩個串列埠之間的通信吞吐量。接收和發送FIFO是獨立的。 數據流向 (RX) 外部的串口設備-------> UART晶元的FIFO,FIFO數據到達trigger level ,觸發中斷-...
繼續訪問
最新發布 對於串口接收數據有丟包如何處理
對於串口接收數據有丟包如何處理
繼續訪問
單片機串口中斷函數中,如果在裡面時間過長,後面來的數據會被自動丟棄嗎?答案是會丟數。很多串口測試實例上位機發送成功,但是下位機接收失敗
單片機串口中斷函數中,如果在裡面時間過長,後面來的數據會被自動丟棄嗎 我來答 分享 舉報 2個回答 #熱議#夫妻之間該做到絕對坦誠嗎? 網路網友b30480f 高粉答主 推薦於2017-09-18·繁雜信息太多,你要學會辨別 關注 不是自動丟棄,而是反復接收,導致後來的數據將先收到、未處理的數據給覆蓋了。 例如對方發給你一串0x01、0x02、0x03,假如你中斷函數太過磨嘰,可能在將0x01從緩沖區中取出後、在處理的過程中又先後收到了0x02、0x03,那麼0x03...
繼續訪問
STM32串口通訊數據丟失原因分析及解決辦法
在進行串口通訊實驗時,一時不仔細可能會發現通訊不正常,數據丟失的現象,包括丟失第一個字元,或只收到最後一個字元等等,本文接下來將就這類問題展開討論。 首先是通過MCU向上位機發送數據: 若程序如下圖所示, 直接發送數據,由於數據緩沖區(TDR)向移位寄存器發送數據是並行發送,時間較快,而從移位寄存器向外傳輸數據是串列輸出,耗時較長,如此可能導致數據丟失多個,或只接收到最後一個,因為後面並行傳輸的快,還沒等數據發送完成,下一個數據就覆蓋住了上一個數據。如此,有兩種解決辦法;一,添加發送...
繼續訪問
C51單片機多機串口通信,帶數據校驗
C51單片機多機串口通信,帶數據校驗,我自己全部編寫的好東西適合你們下載
stc51單片機串口接收多位元組數據
stc51單片機串口接收多位元組數據 簡介 51單片機有2個定時器,一個做串口波特率,一個做數據截止幀延時檢測,硬體平台測試使用的是stc8的單片機,但是可以往51移植 代碼 #include "stc8.h" unsigned char flag=0; //定義標志位,用來判斷接收了多少個字元 void UartInit(void) //[email protected] { SCON = 0x50; //8位數據,可變波特率 AUXR |= 0x40; //定時器1時鍾為Fosc,即1T
繼續訪問
51單片機的串口參數
常用模式為模式1和模式3 1. 波特率可變 2. 起始位為1,停止位為1,數據位為8, 3. 模式3可以選擇奇偶校驗位 ====================================================================== 最近剛好有項目使用到51的串口,整理了一下資料,固先記下,留待後用 模式0: 常用擴展IO 模式1: 波
繼續訪問
51中斷(數據丟失)
51中斷在沒有執行完的情況下,中斷再次發生這時是不會響應第二次中斷的。或者說中斷使能置沒有打開這是來的中斷變不會響應。 其實這是一個很明顯的問題,只是在寫程序的時候,特別遇到多中斷處理的程序時便會產生數據的丟失。而且又是很容易被忽略這么簡單的問題。
繼續訪問
單片機串口調試丟包驗證過程記錄 已解決
單片機串口調試丟包驗證過程記錄 已解決
繼續訪問
串口方面犯的錯誤
串口方面犯的錯誤 項目雖然做得不算多,但是關於串口的程序倒是寫了不少,可能是我太笨了吧,每次寫,每次錯,錯得五花八門,應有盡有,很少能一次性順順當當地搞定,更好笑的是有些錯誤是犯了好幾次的,每次找到這樣的錯誤,我都想給自己一個耳光。就在幾個小時前,我又犯了一個愚蠢的錯誤,痛定思痛,這次一定要總結起來,算是給自己敲個警鍾吧。 程序邏輯錯誤 我通常在串口接收中斷里進行協議的判斷,用不同的狀態量來記錄接收的情況,當完整地接收到一幀數據時,主控部分就可以對數據進行操作了。 假設要接收的數據協議格式為
繼續訪問
記一次串口丟包問題排查
1.項目中需要stm32和JN5169做串口通信,經測試大概有千分之一的丟包率。 2.排查步驟: 2.1.去掉關中斷的地方 2.2.提高串口中斷優先順序 2.3.確定非線路問題 2.4.剪除系統,用裸機跑 3.最終發現,是相同優先順序的中斷搶佔了串口中斷,導致丟包。 ...
繼續訪問
關於Qt5 SerialPort串口傳輸丟失數據問題。
什麼是Qt5 serialPort? 雖然現在大多數的家用PC機上已經不提供RS232介面了。但是由於RS232串口操作簡單、通訊可靠,在工業領域中仍然有大量的應用。Qt以前的版本中,沒有提供官方的對RS232串口的支持,編寫串口程序很不方便。現在好了,在 Qt5.1 中提供了QtSerialPort模塊,方便編程人員快速的開發應用串口的應用程序。 Qt5 serialPort存在的問題。
繼續訪問
串列口數據緩沖寄存器 SBUF 之 初步了解
c52系列的SBUF 有兩個緩沖器 寫SBUF 的操作完成待發送數據的載入,讀SBUF 的操作可獲得已接收到的數據。 兩個操作分別對應兩個不同的寄存器,一個是只寫寄存器,一個是只讀寄存器 在所有的串列通信方式中,在寫入SBUF信號的控制下,把數據裝入相同的九尾移位寄存器,前面八位為數據位元組,其最低位為移位寄存器的輸出位。根據不同的工作方式會自動將1或TB8的值裝入移位寄存器的第九位,並進行發送 串...
繼續訪問
串口丟包
單片機
嵌入式
寫評論
評論
10
3
踩
分享
㈣ 怎樣解決變頻器對單片機干擾的問題
變頻器干擾單片機的主要途徑,就是線路干擾,根據干擾頻段的不同,可以選擇變頻器輸入濾波器、變頻器進線電抗器、磁環等,另外,還需要做好變頻器的接地;如果距離不是很遠的話,建議把變頻器輸出端與電機之間的聯線,換成鎧裝電纜;
綠波傑能希望能幫到您!
㈤ 單片機中mtouch、CCP、ECCP、AUSART、EUSART、FS-USB、ECAN、BOR、PBOR、PLVD、SR-Latch是什麼意思求解
CCP:捕捉、比較、脈寬調制(PWM)。這個模塊可配置為工作在輸入捕捉、定時器比較或 PWM 輸出方式下
ECCP模塊實現為具有增強型 PWM 功能的標准 CCP 模塊。這些功能包括 2 或4 路輸出通道、用戶可選極性、死區控制和自動關閉與重啟。 PWM 的增強型模式,ECCP模塊的捕捉、 比較和單輸出PWM功能與標准 CCP模塊的相同。
AUSART,可定址的通用同步非同步串列口。EUSART,增強型的通用同步非同步串列口。增強型的增加了一些性能,如:波特率自動檢測和校準,更寬的波特率設置范圍,以及一些適應LIN匯流排系統的性能。具體請看數據手冊
BOR(欠壓復位)模塊是基於內部參考電壓電路的。BOR 模塊的主要用途是在發生欠壓條件時
產生器件復位。欠壓條件通常由 AC 電源上的干擾信號(即由於不良的電源傳輸線路造成的 AC
周期波形丟失)或接入大負載時過電流造成電壓下降產生的。
POR:上電復位
PBOR:可編程的掉電鎖定復位。
PLVD :可編程低壓檢測模塊執行中斷驅動的電源電壓檢測功能。電壓檢測監視內部電源電壓。
ECAN 增強型控制器區域網模塊是一個串列介面,用於同其他 CAN 模塊或單片機器件進行通信。