私の連絡先情報
郵便メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
他の CSDN ブロガーによるブログ投稿 (個人使用) 組み込み学習ノート 9-51 マイクロコントローラー UART シリアル通信_51uart シリアル通信-CSDN ブログ
他の CSDN ブロガーが書いたブログ投稿は非常に優れており、51 マイクロコントローラー UART シリアル ポートについて知りたい場合は、クリックして参照してください。
非同期通信通信における2つの文字(8ビット)間の時間間隔は一定ではありませんが、1文字内のビット間の時間間隔は一定であることを意味します。安定した。
UART シリアル通信は、マイクロコントローラーで最も一般的に使用される通信テクノロジであり、通常はマイクロコントローラーとコンピューター間、およびマイクロコントローラー間の通信に使用されます。
コミュニケーションは基本的なタイプに分類できますパラレル通信そしてシリアル通信、パラレル通信では、各ビットのデータが同時に送信され、バイト単位で通信を実現できますが、複数の通信回線は多くのリソースを占有し、コストがかかります。 たとえば、以前に使用した P0 = 0xFF; P0 の 8 個の IO ポートに同時に値を割り当て、同時に信号を出力します。これは、同時に 8 台の車が通過できる 8 レーンと同様です。この形式は、通常、P0、P1、P2、および P3 を 51 マイクロコントローラーの 4 セットのパラレル バスと呼びます。
シリアル通信は車線のようなもので、一度に 1 台の車だけが通過できます。0xFF のようなデータ バイトを送信する場合、車が 1 ビット データをプルすると仮定すると、8 台以上の車が必要になります。同じ時間間隔同じ車線を順番に渡ります。
同期通信と非同期通信の違いは次のとおりです。
1. 同期通信では、受信側のクロック周波数が送信側のクロック周波数と一致している必要があり、送信側は連続したビット ストリームを送信します。非同期通信では、受信側のクロックと送信側のクロックの同期は必要ありません。送信側がバイトを送信した後、次のバイトを送信するまでに任意の長い時間を経過することができます。
2. 同期通信は効率が高く、非同期通信は効率が低い。
3. 同期通信はより複雑で、双方の時計の許容誤差は小さいですが、非同期通信は単純で、双方の時計にはある程度の誤差が許容されます。
4. 同期通信はポイントツーマルチポイントにのみ適しており、非同期通信はポイントツーポイントに使用できます。
STC89C52 マイクロコントローラには、UART シリアル通信に特別に使用される 2 つのピンがあり、1 つは P3^0、もう 1 つは P3^1 という別名もあり、それぞれ RXD (受信データ) および TXD (送信データ) と呼ばれます。それらはシリアルインターフェイスと呼ばれます。図に示すように:
マイクロコントローラーとマイクロコントローラー間の通信:
図中のGNDはマイコンシステム電源の基準グランドを表します。 TXD はシリアル送信ピン、RXD はシリアル受信ピンと呼ばれます。
2 つのマイクロコントローラー間で通信するには、まず電源基準が同じである必要があるため、2 つのマイクロコントローラーの GND が相互に接続されている必要があります。次に、MCU 1 の TXD ピンが MCU 2 の RXD ピンに接続されます。その機能は、MCU 1 が MCU 2 に情報を送信することです。(このプロセスは 2 つの部分に分かれています。MCU 1 の信号を送るマイコン2による処理信号を受信する処理)同様に、マイコン2のTXD端子とマイコン1のRXD端子を接続します。
この概略図は、2 つのマイクロコントローラーが相互に情報を送受信するプロセスを反映しています。
マイクロコントローラー 1 がマイクロコントローラー 2 にデータを送信したい場合、たとえば、バイナリ形式で表現された 1 0xE4 データを送信します。
0b1110 0100、マイクロコントローラー 1 は、送信が開始される前にいくつかの問題に直面しています。
最初に最下位ビットの 0 を送信すると、マイクロコントローラー 1 の TXD ポートを Low レベルに設定する必要があります。
マイクロコントローラーは通常、TTL または CMOS レベルです。TTL/CMOS レベルの標準の場合:
2.0 ボルトを超えるものは高レベル、0.0 ボルト未満は低レベル、その間のロジックは混乱を招くため、デバイスによって判断される可能性があります。レベルが高い場合でも、レベルが低いと判断される場合もあります。したがって、この領域では回路を動作させないでください。このゾーンにあると、製品の当たり外れが決まる可能性があります。したがって、製品を開発する際には、デバイスのデータシートと回路動作時の電圧を確認し、適切な電圧であることを確認する必要があります。
1. TTL レベル:
出力ハイレベル >2.4V、出力ローレベル <0.4V。室温では、一般的な出力ハイレベルは 3.5V、出力ローレベルは 0.2V です。最小入力ハイレベルおよびローレベル: 入力ハイレベル >=2.0V、入力ローレベル <=0.8V、ノイズマージンは 0.4V。
2.CMOSレベル:
1論理レベル電圧は電源電圧に近く、0 論理レベルは 0V に近くなります。ノイズ耐性も広いです。
そこで次のような質問が生じます。
情報の送受信が行われていないとき、マイクロコントローラ1の送信ポート(TXD)はハイレベルまたはローレベル、あるいはその中間の電圧となる。 MCU 2 の受信ポート電圧 (RXD) は、MCU 1 の送信ポートの電圧に従います。 MCU 1 が情報の送信を開始しようとしているという信号をどのように設定するか、つまり、MCU 1 が情報を送信したことを MCU 2 はどのようにして知るのでしょうか?したがって、通信規格を標準化する必要があります。
ステップ 1: 通信が行われていないとき、マイコンの TXD および RXD ポートの電圧は High のままであると規定されています。
ステップ 2: 以下に示すようにデータ送信方法を標準化します。
1 つのスタート ビット、1 つのストップ ビットに加えて、送信されるデータの 1 バイト、合計 8 ビットが定義されていることがわかります。10桁のデータ。
上記の 0xE4 データの送信は、実際には 0 1110 0100 1 を送信します。MCU 1 から MCU 2 への 1 バイトのデータの送信は、実際には 10 ビット全体を送信します。この 10 ビット全体を完全なシリアル データ フレームと呼びます。
スタート ビットとストップ ビットにより、マイクロコントローラー 2 の RXD ポートは、ロー レベルを検出するとデータを受信する準備を開始します。同様に、マイクロコントローラー 1 が 1 バイトのデータを送信したい場合は、まずスタート ビット 0 を送信し (マイクロコントローラー 2 に受信の準備をするように指示)、次にストップ ビット 1 を送信する (マイクロコントローラー 2 に 1 バイトのデータを送信するように指示する) 必要があります。データ移行が完了しました)。データを送信するときは、最初は低く、次に高くなります注文
ステップ 3: 1 ビットのデータを送信するのに必要な時間を一律に設定する必要があります。この時間の速度はボーレート (baud) で表されます。 ボーレート 1 は 1 秒で 1 ビットのデータを送信することを意味し、ボーレート 9600 は 1 秒で 9600 ビットのデータを送信することを意味します。
次に、1ビットを送信した結果を取得します期間=1/ボー. の場合、1 つの完全なデータ フレームを送信するのにかかる時間は次のようになります。10/ボー、データフレーム間の時間間隔は任意です。
MCU 1 と MCU 2 が信号を送信する場合、正しい通信を実現するには、ボー レートを一貫して設定する必要があります。
デスクトップ コンピュータの初期には、通常、このシリアル インターフェイスは RS-232 インターフェイスと呼ばれ、UART 通信に関連していましたが、最近のノートブックにはこの 9 ピン シリアル インターフェイスがありません。そのため、マイクロコントローラーとの通信では USB 仮想シリアル ポートを使用する傾向がますます高まっています。
RS232 で使用されるレベル論理は負論理であり、TTL/CMOS 論理レベルとは異なります。
したがって、コンピュータの 9 ピン RS232 シリアル ポートをマイクロコントローラに直接接続することはできず、次の図を完成させるにはレベル変換チップ MAX232 が必要です。
RS232 ピンの説明:
1. キャリア検出 DCD (データキャリア検出) 2. 受信データ RXD 3. 送信データ TXD
4. データ端末は DTR の準備ができています (データ端末対応) 5. シグナルグランド 6. データレディ DSR(データセット準備完了)
7. RTS の送信要求 (送信リクエスト) 8. CTS をクリアして送信(送信完了) 9. プロンプト RI の呼び出し音 (リンギング)
上図に示すように、RS232のシリアルポート配線では、ピン2、3、5が対応するMAX232ピンに接続されていれば通信を完了できます。
技術の発展に伴い、RS-232 シリアル ポート通信は業界で広く使用されていますが、商用テクノロジの応用では、USB to UART テクノロジが RS232 シリアル ポートに徐々に置き換えられています。
では、図に示すように、マイクロコントローラーとコンピューター間の通信をどのように実現するか
この場合、これは、この機能を実現するために USB - シリアル ポート チップ CH340T を使用する開発ボードです。
マイクロコントローラー ポート TXD は、ジャンパー キャップを使用して USB-TX に接続し、同時に CH340 ピン 4 RXD ポートに接続します。
マイクロコントローラー ポート RXD は、ジャンパー キャップを使用して USB-RX に接続し、CH340 の 3 番目のピン TXD に接続します。
STC89C52 マイクロコントローラーはプログラムのダウンロード時にコールド スタートが必要なため、USB-RX と CH340 の 3 番目のピン TXD の間に 4148 ダイオードが直列に接続されていることがわかります。最初にダウンロードをクリックしてから電源をオンにするだけです。
いわゆるコールドスタートこれは、電源オフから電源オンまでのマイクロコントローラーの起動プロセスを指しますが、ホット スタートはマイクロコントローラーの電源が常にオンであることを意味します。コールド スタートとホット スタートの違いは、コールド スタート中はマイクロコントローラーの内部 RAM の値がランダムな量であるのに対し、ホット スタート中はマイクロコントローラーの内部 RAM の値は変更されず、起動前と同じ状態のままです。
電源投入時に、マイクロコントローラーはまずプログラムをダウンロードする必要があるかどうかを検出しますが、CH340T のピン 3 は出力ピンであるため、マイクロコントローラーの VCC はスイッチによって制御されます。ダイオードの場合、電源がオフになるとスイッチの後続のマイコンが故障します。CH340T のピン 3 はマイコンの P3.0 (RXD) ピンに接続され、電流はこのピンを介して後段の回路に流れ込み、コンデンサを充電します。この電圧は 2 ~ 3V 程度ですが、通常のコールドスタートに影響を与える可能性があります。ダイオードを追加すると、通信に影響を及ぼさない一方で、この悪影響を排除できます。
P3.0が準双方向IOポートであることをマイコンのマニュアルで知りました。
赤枠部分が準双方向IOポートです。 、内部出力ビットがローレベルの場合、NOTゲートを介してトランジスタのベースがハイレベルになり、トランジスタがオンになり(飽和導通ではCEの両端の電圧がほぼ同じになります)、IOがオンになります。マイコンのポートは、外部からキースイッチが押されているかポップアップされているかに関係なく、IO ポートはローレベルを出力します。つまり、外部信号によって制御されません。
内部出力がハイレベルの場合、NOT ゲートを通過した後、トランジスタのベースは非常に低く、トランジスタは導通していません (CE の両端の抵抗は非常に大きく、抵抗 R は CE に比べて無視できます)このとき、IO ポートの出力はハイレベルになります。ボタンが押されると、IO ポートが接地され、IO ポートは Low レベルを出力します。
このことから、次の場合にのみ、IOポート出力はハイレベルですいつ、IOポートの出力は外部回路によって制御されます。
したがって、P3.0 が RXD ポートとして使用される場合、P3.0 の内部出力は常に High であることがわかります。P3.1TXD ポートはトランスミッターとして機能し、内部出力レベル必要に応じて上下に変更できます。
および: TTL レベルの場合
出力端子: ハイレベル >=2.4V、ローレベル <=0.4V;
受信端: ハイレベル >=2.0V、ローレベル <=0.8V。
COMSレベルの場合
出力端子:ハイレベル=Vcc、ローレベル=GND(Vccは電源電圧)
受信端: ハイレベル >=0.7Vcc、ローレベル <=0.2Vcc。
受信端の論理レベルと出力端の論理レベルの間には、まだいくらかの電圧差があります。これは、信号伝送中に発生する電圧降下の干渉または保護回路の存在による可能性があるため、ダイオードを追加しても問題はありません。送信電圧がわかりにくい論理領域にあることが原因です。
IO ポートを使用して UART シリアル通信をシミュレートする
上部プログラム:
- # include<reg52.h>
-
- sbit PIN_RXD = P3^0; //接受引脚定义
- sbit PIN_TXD = P3^1; //发送引脚定义
-
- bit RxdorTxd = 0; //指示当前状态为接受还是发送
- bit RxdEnd = 0; //接受结束标志
- bit TxdEnd = 0; //发送结束标志
- unsigned char RxdBuf = 0; //接收缓冲区
- unsigned char TxdBuf = 0; //发送缓冲器
-
- void ConfigUART(unsigned int baud);
- void StartTXD(unsigned char dat);
- void StartRXD();
-
-
- void main()
- {
- EA = 1; //打开总中断
- ConfigUART(9600); //配置波特率为9600
-
- while(1)
- {
- while(PIN_RXD); //等待接收引脚出现低电平,即起始位
- StartRXD(); //启动接收
- while(!RxdEnd); //等待接受完成
- StartTXD(RxdBuf +1);//接受到的整数+1后,发送回去
- while(!TxdEnd); //等待发送结束
- }
- }
-
- /* 串口配置函数,baud-通信波特率 */
- void ConfigUART(unsigned int baud)
- {
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x02; //配置T0为模式2
- TH0 = 256 - (11059200/12)/baud; //计数T0的重载值
- }
-
- /* 启动串行接受 */
- void StartRXD()
- {
- TL0 = 256 - ((256-TH0) >> 1);//接受启动时T0定时为半个波特率周期
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- RxdEnd = 0; //清零接受结束标志
- RxdorTxd = 0; //设置当前状态为接受 1位发送
-
- }
-
- /* 启动串行发送,dat-待发送字节数据 */
- void StartTXD(unsigned char dat)
- {
- TxdBuf = dat; //待发送数据保存到发送缓冲器
- TL0 = TH0; //T0计算初值为重载值
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- PIN_TXD = 0; //发送起始位
- TxdEnd = 0; //清零发送结束标志
- RxdorTxd = 1; //设置当前状态为发送
- }
-
- /*T0中断服务函数,处理串行发送和接收 */
- void interruptTimer0() interrupt 1
- {
- static unsigned char cnt = 0;
-
- if(RxdorTxd)
- {
- cnt++;
- if(cnt <= 8) //低位在先一次发送8bit数据位
- {
- PIN_TXD = TxdBuf & 0x01;
- TxdBuf >>= 1;
- }
- else if(cnt == 9) //发送停止位
- {
- PIN_TXD = 1;
- }
- else //发送结束
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- TxdEnd = 1; //置发送结束标志
- }
- }
-
- else //串行接收处理
- {
- if(cnt == 0) // 处理起始位
- {
- if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接受数据位
- {
- RxdBuf = 0;
- cnt++;
- }
- else //起始位为1(不为0)时,中止接收
- {
- TR0 = 0; //关闭T0
- }
- }
- else if(cnt <= 8) //处理8位数据位
- {
- RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
- if(PIN_RXD) //接收脚为1时,缓冲器最高位置1
- { //而为0时不处理即仍保持位移后的0
- RxdBuf |= 0x80;
- }
- cnt++;
- }
- else //停止位处理
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- if(PIN_RXD) //停止位为1时,方认为数据有效
- {
- RxdEnd = 1; //置接收结束标志
- }
- }
- }
-
- }
作業ロジックマップ
このプログラムはタイマー 0 を使用して UART シリアル通信をシミュレートするだけであることに注意してください。シミュレーションプログラム。このプログラムは、コンピュータとマイクロコントローラ間の通信を実現します。通信結果は、コンピュータが送信したデータをマイコンに送信し、マイコンはデータに1を加算してコンピュータに送り返します。 STC-ISP に付属のシリアル ポート デバッグ アシスタントを使用して、この結果を示します。
まず、上の写真がすべて COM3、ボーレートが 9600、チェック ビットが NO、データ ビットが 8、ストップ ビットが 1 であることを確認します (ここで設定されているのはコンピュータのビットです)。シリアルポートパラメータ)
結果を見てください:正常に通信可能ですタイマー 0 はシリアル通信をシミュレートします_bilibili_bilibili
このプログラムの動作ロジックを簡単に説明します。送信モジュールたとえば、最下位ビットから 0xAA =1010 1010 を送信します。
それは TxdBuf = 1010 1010 プログラムを見てください
- if(RxdorTxd)
- {
- cnt++;
- if(cnt <= 8) //低位在先一次发送8bit数据位
- {
- PIN_TXD = TxdBuf & 0x01;
- TxdBuf >>= 1;
- }
- else if(cnt == 9) //发送停止位
- {
- PIN_TXD = 1;
- }
- else //发送结束
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- TxdEnd = 1; //置发送结束标志
- }
- }
初め割り込み入力 cnt = 1
PIN_TXD = TxdBuf & 0x01、つまり 1010 1010 0000 0001 の AND の結果は、0xAA の最下位ビットを送信ポートに割り当てて、対応するレベルを有効にします。初めて割り込み TXD ポートに入力される電圧は低レベルであり、このプロセスは 2 番目の割り込みが発生するまで継続することがわかります。
次に、TxdBuff が 1 ビット右にシフトされます。つまり、TxdBuf = 0101 0101
それから2回目割り込み
数 = 2
PIN_TXD = 1 今回は送信ポートのレベルがハイレベルです
送信バッファ = 0010 1010
それから3回目と4回目まで8回目
数 = 8
PIN_TXD = 1 で設定されるレベルはハイレベルで、送信データの最上位ビット 1 です。
このとき TxdBuf = 0x00
その後9回目9 回目に割り込みが入るということは、データ ビットが送信されたばかりで、ストップ ビットの送信を準備するときであることを意味します。
したがって、PIN_TXD = 1、送信ポートは直接ハイレベルに割り当てられます。
最後の 10 番目の割り込みは、ストップ ビットも送信されたことを表します。したがって、cntリセットには0が割り当てられ、TR0には0が割り当てられ、タイマ0はオフになり、TXDEnd = 1になり、送信終了フラグは1に設定され、完全なデータフレームの送信が完了します。
その後受信モジュール: この関数では、先に 0xAA を送信しましたが、その値は受信データに 1 を加算した結果であるため、受信データは 0xA9 =1010 1001 となります。
- void StartRXD()
- {
- TL0 = 256 - ((256-TH0) >> 1);//接受启动时T0定时为半个波特率周期
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- RxdEnd = 0; //清零接受结束标志
- RxdorTxd = 0; //设置当前状态为0接收 1为发送
-
- }
- else //串行接收处理
- {
- if(cnt == 0) // 处理起始位
- {
- if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接受数据位
- {
- RxdBuf = 0;
- cnt++;
- }
- else //起始位为1(不为0)时,中止接收
- {
- TR0 = 0; //关闭T0
- }
- }
- else if(cnt <= 8) //处理8位数据位
- {
- RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
- if(PIN_RXD) //接收脚为1时,缓冲器最高位置1
- { //而为0时不处理即仍保持位移后的0
- RxdBuf |= 0x80;
- }
- cnt++;
- }
- else //停止位处理
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- if(PIN_RXD) //停止位为1时,方认为数据有效
- {
- RxdEnd = 1; //置接收结束标志
- }
- }
- }
実際、送信処理と受信処理は似ていることがわかります。データの受信では、主に cnt と連携するために最初の割り込みを 0 回目から開始するようにマークしました。
図に示すように、0 回目の割り込みにかかる時間は、あらかじめ設定されている割り込み時間の半分であることがわかります。これは、レベル信号が 0 か 1 かを確認する際に、早い段階でレベルが入っているためです。サンプリング時間には誤差や干渉が発生する可能性があるため、一般にサンプリングポイントは信号伝送時間の中間点に設定され、そこのレベル信号がその時間帯に伝送された信号とみなされます。したがって、受信モジュールは、最初にスタートビットを受信するときに割り込み時間を元の半分に設定するだけで済み、後続のすべての信号収集ポイントが中心点にあることが保証されます。
プログラムがどのように設定されているかを見てみましょう: TL0 = 256 - ((256-TH0) >> 1) // 開始時の T0 タイミングはボーレート周期の半分であることを受け入れます。
256-TH0 は、事前に設定された割り込み時間です。先ほどの割り込み時間の半分になるようにプログラム操作を行います。バイナリ 0000 1000 の例を考えてみましょう。これを 1 ビット右にシフトすると、0000 0100 = 4 になります。1 ビット右にシフトする操作は、数値を元の値の半分に変更することであることがわかります。 同様に、1 ビット左シフトの結果は 0001 0000 =16 になります。これは、元の数値を 2 倍することを意味します。
プログラムプロセス解析を開始する
RxdorTxd が 0 の場合、else 関数に入ります。0回目割り込みに入ると、時間領域での受信モジュールの開始点はスタート ビットの中間点になります。まずポート電圧が本当に低いかどうかを判断し、そうでない場合は割り込みをオフにします。なぜこれを行うのでしょうか?
これは受信モジュールであるため、RXD の電圧はマイコンによって制御されません。この場合、CH340T の TXD 端子の電圧を制御するコンピュータによって制御されます。マイコンの RXD の電圧は CH340TXD 端に従います。受信側では、受信した情報が妨害される可能性があるため、再度確認する必要があります。
「はい」の場合は cnt++、cnt=1 になります。 RxdBuf = 0; 受信バッファを 0 にクリアします。
その後1位(実は二回目)二流割り込み cnt = 1 を入力し、else if() 関数を入力して、段階的にデータをバッファに転送します。その後のプロセスについては詳細には説明しませんので、興味のある方はプログラム ロジックに従ってご自身で実行してください。最初に下位ビット、次に上位ビットの方法でデータが実際にバッファ変数に格納できるかどうかを確認します。前回のブログ投稿では、この関数は左シフト方式を使用して最初にデータの上位ビットを格納したためです。このアプローチは、別の作業方法を完全に補完します。
この時点で、プログラムはタイマー 0 を使用して UART シリアル通信をシミュレートします。
3 つの基本的なコミュニケーション
単信通信:一方のみが相手に情報を送信することができ、相手はテレビのリモコンやラジオ放送などの情報を送り返すことはできません。
半二重通信: データは 2 者間で送信できますが、同時に一方の当事者のみがデータをもう一方の当事者に送信できます。たとえば、トランシーバーは典型的な半二重通信です。 上記のシリアルポートシミュレーションプログラムは、半二重通信としても理解できます。
全二重通信: データを送信しながら受信することができ、電話通信のようにこの 2 つが同時に実行されます。
IO ポート シミュレーション シリアル通信は基本的にシリアル通信の本質を示していますが、マイクロコントローラー プログラムはマイクロコントローラーの IO ポートで受信したデータを常に検出してスキャンする必要があるため、マイクロコントローラーの実行時間の多くがかかります。したがって、51 マイクロコントローラ内にはデータを自動的に受信できる UART モジュールがあり、それを正しく使用するには、特殊機能レジスタを正しく設定する必要があります。
SCONシリアル制御レジスタ
このケースではモード 1 のみが導入されています。つまり、SM1 = 1 および SM0 = 0 に設定するのがモード 1 です。このモードは、前のシミュレートされたシリアル通信で使用されたデータ フレーム フォーマットです: 1 スタート ビット、8 データ ビット、および 1 ストップ ビット。
アナログ シリアル通信では、ボー レートを表現するためにタイマ 0 が使用されます。STC89C52 UART モジュールのボー レート トランスミッタは、タイマ T1 またはタイマ T2 によってのみ生成できます。これは、アナログ通信の概念とはまったく異なります。
タイマー T2 を使用する場合は、追加の構成レジスタが必要になります。デフォルトでは、タイマー T1 が使用されます。
プログラムコード:
- # include<reg52.h>
-
- void ConfigUART(unsigned int baud);
-
- void main()
- {
- EA = 1;
- ConfigUART(9600); //配置波特率为9600
- while(1);
-
- }
- /* 串口配置函数,baud-通信波特率 */
- void ConfigUART(unsigned int baud)
- {
- SCON = 0x50; //0x50= 0101 0000 配置串口为模式1
- TMOD &= 0x0F; //清零T1的控制位
- TMOD |= 0x20; //0x20 = 0010 0000 配置T1的为模式2自动重载模式
- TH1 = 256 - (11059200/12/32)/baud; //计算T1的重载值
- TL1 = TH1; //设置初值
- ET1 = 0; //禁止T1中断
- ES = 1; //启动串口中断
- TR1 = 1; //启动T1定时器
- }
-
- /*UART中断服务函数 */
- void interruptUART() interrupt 4
- {
- if(RI) //接收到字节
- {
- RI = 0; //软件清0接收中断标志
- SBUF = SBUF+1;//接收的数据+1,左边是发送SBUF,右边是接收SBUF
-
- }
- if(TI)
- {
- TI = 0; //软件清0发送中断标志位
- }
-
- }
結果のビデオをご覧ください。モジュールシリアル通信_bilibili_bilibiliが付属しています
通常の通信が問題なく行われていることが確認できた後、プログラム内の関連する内容について簡単に説明します。
タイマ T1 のリロード値の計算式は次のとおりです。
TH1 = TL1 = 256 - 水晶発振器の値/12/2/16/ボーレート、およびその値
割り込み間隔時間 = 水晶発振器の値/12/2/16/ボーレート = 水晶発振器の値/12*(1/ボーレート)*(1/32)
水晶発振器の値/12 は 1 秒間のマシン サイクル数を意味し、(1/ボー レート) は 1 ビットのデータを送信するのに必要な時間を意味します。
水晶発振器の値/12* (1/ボーレート) は、1 ビットのデータを送信するために必要なマシンプロセッサの数を意味します。
同様に、水晶発振器の値/12*(1/ボーレート)*(1/32) この割り込みの時間 = 1 ビットのデータを送信する時間の 1/32
つまり、1 ビットのデータ転送は 32 の時間間隔に分割されます。
計算結果は 3、つまり割り込み間隔 = 3 マシンサイクルとなり、この時間は非常に短いです。
シリアルポートモジュールの信号サンプリング方式は、1 つの信号を 16 回収集し、7 回目、8 回目、9 回目の信号レベルを取り出すことになっているため、3 回のうち 2 回がハイレベルであればデータとみなされます。レベルが 2 回 0 の場合、このビットは 0 であるとみなされます。このようにして、予期せぬ干渉によりデータが誤って読み取られた場合でも、最終データの正確性は保証されます。
下の写真は、主に説明の便宜を目的として推奨ブログ投稿からのものです。:ボーレートの計算式
SMOD はパワー レジスタ PCON によって制御されます。デフォルトでは、SMOD は 0 です。これを上記の式に代入すると、前の初期値の解の式が得られます。
TH1 = TL1 = 256 - 水晶発振器の値/12/2/16/ボーレート
レジスタの最高値が 1 PCON |= 0x80 に設定されている場合、つまり SMOD が 1 に設定されている場合、上の式に示すように、ボー レートを 2 倍にすることができます。
このとき、T1 の初期値は TH1 = TL1 = 256 - 水晶振動子の値 / 12 / 16 / ボーレート となります。
ここで一つ注意しなければならないのは、: PCON レジスタを使用して波形レートを 2 倍に制御する場合は、その初期値の式を次のように記述する必要があります。
TH1 = TL1 = 256 - 水晶発振器の値/12/2/16/ボーレートはちょうど
現在のリロード値は TH1=256 - (11059200/12/32)/baud =256-(11059200/12/16)/(2*buad) baud*2=4800*2=9600、9600 は現在のプログラムのボーレート
初期値のリロード会社が TH1 = TL1 = 256 - 水晶発振器の値/12/16/ボー レートを書き込んだ場合、現在のボー レートは 9600 ではなく 4800 のままです。シリアル通信ソフトウェアを使用して通信ボーレートを9600に設定すると、結果は間違っています。
ビデオを見る:ボーレート関連_bilibili_bilibili
ボーレート 9600 の時間間隔はわずか 3 マシン サイクルであり、14400 の時間間隔は 2 マシン サイクルであることがわかります。ボーレートが高い場合、その時間間隔は 1 マシン サイクル未満になる可能性があることがわかります。したがって、別の動作モード、つまり PCON の最上位ビットが 1 に設定された後の ConfigUART(9600) が存在します。その現在のボー レートは 19200 ですが、その時間間隔は元の 9600 ボー レートの時間間隔です。 3 マシンサイクル。
タイマ 0 のシミュレートされたシリアル通信とシリアル通信モジュールの動作にはまだ多くの違いがあることに注意してください。シリアル通信モジュールは 1 つの入出力を完了し、シリアル通信の割り込みは 2 回だけ発生します。 RI が 1 に設定されると 1 回、TI が 1 に設定されると 1 回、その後ソフトウェアによってクリアされます。送信プロセスを意識する必要はなくなり、送信が完了したかどうかだけに注目し、送信が完了したらシグナルを送信します。
シリアル通信の送受信回路には物理的に同一の SBUF レジスタが 2 つあり、アドレスも 0x99 ですが、1 つは送信バッファ、もう 1 つは受信バッファとして使用されます。これは、部屋が 2 つあり、その 2 つの部屋の番地が同じであることを意味します。一方は出入りできますが、もう一方は出入りできません。このようにして、相互に干渉することなく、UART の全二重通信を実現できます。ただし、論理的には、毎回 SBUF のみが操作され、マイクロコントローラーは、SBUF に対して「読み取り」操作を実行するか「書き込み」操作を実行するかに基づいて、SBUF を受信するか送信するかを自動的に選択します。
シリアル通信プログラムの基本的な手順:
1. シリアルポートをモード 1 に設定します。
2. タイマー T1 をモード 2 (自動再インストール モード) に設定します。
3. ボーレートに基づいて TH1 と TL1 の初期値を計算します。必要に応じて、PCON を使用してボーレートを 2 倍にすることができます。
4. タイマ制御レジスタ TR1 を開き、タイマを実行させます。注: シリアル ポート割り込みを使用する場合、タイマー 2 シリアル ポート割り込みを使用しない限り、タイマー 1 割り込みを有効にすることはできません。