minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
As postagens escritas por outros blogueiros da CSDN são muito boas. Se você quiser saber sobre a porta serial UART do microcontrolador 51, clique e dê uma olhada:
Comunicação assíncronaIsso significa que o intervalo de tempo entre dois caracteres (8 bits) na comunicação não é fixo, mas o intervalo de tempo entre bits dentro de um caractere éestábulo。
A comunicação serial UART é a tecnologia de comunicação mais comumente usada para microcontroladores. Geralmente é usada para comunicação entre microcontroladores e computadores e entre microcontroladores.
A comunicação pode ser dividida em tipos básicosComunicação paralelaecomunicação em série, Na comunicação paralela, cada bit de dados é transmitido simultaneamente e a comunicação pode ser realizada em bytes. No entanto, múltiplas linhas de comunicação ocupam muitos recursos e são caras. Por exemplo, P0 = 0xFF usado antes, atribui valores às 8 portas IO de P0 ao mesmo tempo e emite sinais ao mesmo tempo, semelhante a 8 pistas que podem passar por 8 carros ao mesmo tempo. Esta forma é paralela. Costuma-se chamar P0, P1, P2 e P3 aos quatro conjuntos de barramentos paralelos do microcontrolador 51.
A comunicação serial é como uma pista, apenas um carro pode passar por vez.Se um byte de dados como 0xFF for transmitido, supondo que um carro esteja extraindo dados de 1 bit, serão necessários mais de 8 carros.mesmo intervalo de tempoAtravesse a mesma faixa por sua vez.
A diferença entre comunicação síncrona e comunicação assíncrona:
1. A comunicação síncrona requer que a frequência do clock da extremidade receptora seja consistente com a frequência do clock da extremidade emissora, e a extremidade emissora envie um fluxo de bits contínuo, a comunicação assíncrona não requer sincronização do relógio final receptor e do relógio final emissor; Depois que o final do envio envia um byte, ele pode passar por qualquer intervalo de tempo longo antes de enviar o próximo byte.
2. A comunicação síncrona tem alta eficiência, enquanto a comunicação assíncrona tem baixa eficiência.
3. A comunicação síncrona é mais complicada e o erro permitido dos relógios de ambas as partes é pequeno; a comunicação assíncrona é simples e os relógios de ambas as partes podem permitir um certo erro;
4. A comunicação síncrona é adequada apenas para ponto a multiponto, e a comunicação assíncrona pode ser usada para ponto a ponto.
O microcontrolador STC89C52 possui dois pinos usados especificamente para comunicação serial UART, um é P3^0 e o outro é P3^1. Eles também possuem outros nomes chamados RXD (Receber Dados) e TXD (Transmitir Dados) respectivamente. eles são chamados de interface serial. Como mostrado na imagem:
Comunicação entre microcontrolador e microcontrolador:
Na figura, GND representa o aterramento de referência da fonte de alimentação do sistema microcontrolador. TXD é chamado de pino de transmissão serial e RXD é o pino de recepção serial.
Para a comunicação entre dois microcontroladores, em primeiro lugar, a referência da fonte de alimentação deve ser a mesma, portanto os GNDs dos dois microcontroladores devem estar conectados entre si.Em seguida, o pino TXD do MCU 1 é conectado ao pino RXD do MCU 2. A função é que o MCU 1 envie informações para o MCU 2. (Este processo é dividido em duas partes. MCU 1’senviar sinalProcesso com Microcontrolador 2receber sinalProcesso) Da mesma forma, o pino TXD do microcontrolador 2 é conectado ao pino RXD do microcontrolador 1.
Este diagrama esquemático reflete o processo de dois microcontroladores enviando e recebendo informações um para o outro.
Quando o microcontrolador 1 deseja enviar dados ao microcontrolador 2, por exemplo, enviando 1 dado 0xE4, expresso em forma binária:
0b1110 0100, o microcontrolador 1 enfrenta vários problemas antes do início da transmissão:
Suponha que eu transmita primeiro o bit mais baixo de 0, então preciso definir a porta TXD do microcontrolador 1 para nível baixo.
Os microcontroladores são geralmente de nível TTL ou CMOS. Para padrões de nível TTL/CMOS:
Qualquer valor superior a 2,0 volts é um nível alto, algo inferior a 0,0 volts é um nível baixo e qualquer valor intermediário não é um nível alto nem um nível baixo. A lógica intermediária será confusa e poderá ser avaliada pelo dispositivo. um nível alto, também pode ser considerado um nível baixo. Portanto, tente não operar o circuito nesta área. Estar nesta zona pode fazer com que seu produto seja um sucesso ou um fracasso. Portanto, ao desenvolver produtos, é necessário verificar a ficha técnica do dispositivo e a tensão durante a operação do circuito para garantir que ele esteja em uma tensão adequada.
1. Nível TTL:
Alto nível de saída> 2,4 V, nível baixo de saída <0,4 V. À temperatura ambiente, o nível alto de saída geral é 3,5 V e o nível baixo de saída é 0,2 V. Nível alto e baixo de entrada mínima: nível alto de entrada> = 2,0 V, nível baixo de entrada < = 0,8 V, margem de ruído é 0,4 V.
2. Nível CMOS:
1nível lógico A tensão está próxima da tensão de alimentação e o nível lógico 0 está próximo de 0V. E tem uma ampla tolerância ao ruído.
Então aí vem a pergunta:
Quando a informação não está sendo transmitida ou recebida, a porta de transmissão (TXD) do microcontrolador 1 estará em um nível alto ou baixo, ou a tensão da porta estará entre estes. A tensão da porta receptora (RXD) do MCU 2 segue a tensão da porta de transmissão do MCU 1. Como definir o sinal de que o MCU 1 está prestes a começar a transmitir informações, ou seja, como o MCU 2 sabe que o MCU 1 transmitiu informações para ele? Portanto, há uma necessidade de padronizar os padrões de comunicação.
Passo 1: Fica estipulado que quando não ocorre a comunicação, a tensão das portas TXD e RXD do microcontrolador permanece alta.
Etapa 2: Padronize o método de transmissão de dados conforme mostrado abaixo
Você pode ver que ele define 1 bit de início, 1 bit de parada, mais 1 byte de dados a serem transmitidos, o que dá um total de 8 bits.Dados de dez dígitos。
A transmissão de dados 0xE4 mencionada acima, na verdade, transmite 0 1110 0100 1. A transmissão de 1 byte de dados do MCU 1 para o MCU 2, na verdade, transmite dados de 10 bits. Esse todo de 10 bits é chamado de quadro de dados serial completo.
Com o bit de início e o bit de parada, a porta RXD do microcontrolador 2 começa a se preparar para receber dados quando detecta um nível baixo. Da mesma forma, se o microcontrolador 1 quiser enviar 1 byte de dados, ele precisa primeiro enviar um bit de início 0 (instruir o microcontrolador 2 para prepará-lo para receber) e, em seguida, enviar um bit de parada 1 (informar ao microcontrolador 2 um byte de transferência de dados concluída).E ao transmitir dados, éPrimeiro baixo, depois altoOrdem
Etapa 3: Você precisa definir uniformemente o tempo necessário para transmitir 1 bit de dados. A velocidade desse tempo é expressa pela taxa de transmissão (baud). Uma taxa de transmissão de 1 significa transmitir 1 bit de dados em 1 segundo, e uma taxa de transmissão de 9.600 significa transmitir 9.600 bits de dados em 1 segundo.
Então obtemos o resultado da transmissão de 1 bitduração=1/baud., então o tempo para transmitir 1 quadro de dados completo pode ser considerado10/baud,O intervalo de tempo entre os quadros de dados é arbitrário.
Quando o MCU 1 e o MCU 2 transmitem sinais, suas taxas de transmissão devem ser definidas para serem consistentes para obter a comunicação correta.
Nos primeiros anos dos computadores desktop, geralmente havia uma interface serial de 9 pinos. Essa interface serial é chamada de interface RS-232, que está relacionada à comunicação UART. No entanto, os notebooks modernos não possuem mais essa interface serial de 9 pinos. portanto, a comunicação com microcontroladores tende cada vez mais a usar portas seriais virtuais USB.
A lógica de nível usada pelo RS232 é lógica negativa, que é diferente dos níveis lógicos TTL/CMOS.
Portanto, a porta serial RS232 de 9 pinos do computador não pode ser conectada diretamente ao microcontrolador. Um chip de conversão de nível MAX232 é necessário para completar a seguinte figura:
Descrição do pino RS232:
1. Detecção de portadora DCD (detecção de portadora de dados) 2. Receber dados RXD 3. Enviar dados TXD
4. O terminal de dados está pronto para DTR (Terminal de dados pronto) 5. Terra do sinal 6. DSR pronto para dados (Conjunto de dados pronto)
7. Solicitação de envio de RTS (Solicitação de envio) 8. Limpe e envie CTS(Pronto para enviar) 9. Alerta de toque RI (Toque)
Conforme mostrado na figura acima, na fiação da porta serial RS232, a comunicação pode ser concluída desde que os pinos 2, 3 e 5 estejam conectados aos pinos MAX232 correspondentes.
Com o desenvolvimento da tecnologia, a comunicação da porta serial RS-232 é amplamente utilizada na indústria. No entanto, na aplicação da tecnologia comercial, a tecnologia USB para UART substituiu lentamente a porta serial RS232.
Então, como realizar a comunicação entre o microcontrolador e o computador conforme mostrado na figura
Esta é a placa de desenvolvimento, neste caso, que usa o chip USB para porta serial CH340T para realizar esta função.
A porta TXD do microcontrolador usa um jumper para conectar ao USB-TX e é conectada à porta RXD do pino 4 do CH340 ao mesmo tempo.
A porta RXD do microcontrolador usa um jumper para conectar ao USB-RX e é conectada ao TXD de terceiro pino do CH340.
Você pode ver que existe um diodo 4148 em série entre o USB-RX e o terceiro pino TXD do CH340, pois o microcontrolador STC89C52 precisa de uma inicialização a frio ao baixar o programa. Basta clicar em download primeiro e depois ligar.
assim chamadoPartida a frio Refere-se ao processo de inicialização do microcontrolador, desde o desligamento até a ligação, enquanto a inicialização a quente significa que o microcontrolador está sempre ligado; A diferença entre partida a frio e partida a quente é: durante a partida a frio, os valores na RAM interna do microcontrolador são quantidades aleatórias, enquanto durante a partida a quente, os valores na RAM interna do microcontrolador não serão alterados e permanecem os mesmos de antes da inicialização.
No momento de ligar, o microcontrolador detectará primeiro se é necessário baixar o programa Embora o VCC do microcontrolador seja controlado pela chave, pois o pino 3 do CH340T é um pino de saída, caso não exista. diodo, o microcontrolador subsequente do switch falhará quando a energia estiver desligada. O pino 3 do CH340T está conectado ao pino P3.0 (RXD) do microcontrolador. A corrente fluirá para o circuito do estágio subsequente através deste pino e carregará o capacitor. o estágio subsequente, resultando em uma certa tensão no estágio subsequente. Esta tensão, embora o valor seja de apenas cerca de 2 ~ 3 V, pode afetar a partida a frio normal. Após adicionar um diodo, por um lado não afeta a comunicação, por outro pode eliminar este efeito adverso.
Aprendi no manual do microcontrolador que P3.0 é uma porta IO quase bidirecional.
A parte da caixa vermelha é a porta IO quase bidirecional , quando o bit de saída interno está em nível baixo, através da porta NOT, a base do transistor está em nível alto, o transistor está ligado (a tensão em ambas as extremidades do CE é quase a mesma na condução saturada) e o IO A porta do microcontrolador produz um nível baixo, independentemente do externo. Quer a chave seja pressionada ou aberta, a porta IO permanece baixa. Ou seja, não é controlado por sinais externos.
Quando a saída interna é de alto nível, depois de passar pela porta NOT, a base do transistor está extremamente baixa e o transistor não está conduzindo (a resistência em ambas as extremidades do CE é muito grande e a resistência R é insignificante em comparação com Neste momento, a saída da porta IO está alta. Quando o botão é pressionado, a porta IO é aterrada e a porta IO emite um nível baixo.
A partir disso, pode-se ver que somente quandoA saída da porta IO é de alto nívelquando,A saída da porta IO é controlada pelo circuito externo。
Portanto, sabemos que a saída interna do P3.0 é sempre alta quando é utilizada como porta RXD.A porta P3.1TXD serve como transmissor e seuNível de saída internoPode ser alterado para cima ou para baixo conforme necessário.
E: para níveis TTL
Terminal de saída: alto nível >=2,4V, baixo nível <=0,4V;
Extremidade de recepção: nível alto >=2,0V, nível baixo <=0,8V.
Para nível COMS
Terminal de saída: nível alto = Vcc, nível baixo = GND (Vcc é a tensão de alimentação);
Extremidade de recepção: nível alto >=0,7Vcc, nível baixo <=0,2Vcc.
Ainda existe alguma diferença de tensão entre o nível lógico da extremidade receptora e o nível lógico da extremidade de saída. Isso pode ser devido à interferência de queda de tensão gerada durante a transmissão do sinal ou à existência de um circuito de proteção, portanto, adicionar um diodo não será necessário. causa isso. A tensão transmitida está em uma área lógica confusa.
Use a porta IO para simular a comunicação serial UART
Programa superior:
- # 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; //置接收结束标志
- }
- }
- }
-
- }
Mapa lógico de trabalho
Este programa usa o temporizador 0 para simular a comunicação serial UART. Observe que isso é apenas um.Programa de simulação. Este programa implementa a comunicação entre o computador e o microcontrolador. Seu resultado de comunicação é transmitir os dados transmitidos pelo computador para o microcontrolador, e o microcontrolador adiciona 1 aos dados e os envia de volta ao computador. Use o assistente de depuração de porta serial que acompanha o STC-ISP para demonstrar esse resultado.
Primeiro, certifique-se de que as portas sejam iguais. As imagens acima são todas COM3, a taxa de transmissão é 9600, o bit de verificação é NÃO, o bit de dados é 8 e o bit de parada é 1. (O que está definido aqui é o do computador. parâmetros da porta serial)
Dê uma olhada no resultado: a comunicação normal é possívelO temporizador 0 simula comunicação serial_bilibili_bilibili
Explique resumidamente a lógica de funcionamento deste programa: paraEnviar móduloPor exemplo, envie 0xAA =1010 1010 começando no bit mais baixo
Isso é TxdBuf = 1010 1010Veja o programa
- 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; //置发送结束标志
- }
- }
primeiroDigite interrupção cnt = 1
PIN_TXD = TxdBuf & 0x01, ou seja, o resultado do AND de 1010 1010 0000 0001 é atribuir o bit mais baixo de 0xAA à porta de envio para habilitar o nível correspondente. Pode-se observar que a tensão que entra na porta TXD de interrupção pela primeira vez é de nível baixo, e esse processo continuará até que ocorra a segunda interrupção.
Então TxdBuff é deslocado um bit para a direita, ou seja, TxdBuf = 0101 0101
Entãoa segunda vezinterromper
cnt = 2
PIN_TXD = 1 Desta vez o nível da porta de envio é de alto nível
TxdBuf = 0010 1010
Então a terceira e quarta vezes até8ª vez
cnt = 8
O nível definido por PIN_TXD = 1 é de nível alto, que é o bit 1 mais alto dos dados transmitidos.
Neste momento TxdBuf = 0x00
Depois disso9ª vezEntrando na interrupção. A 9ª entrada na interrupção significa que os bits de dados acabaram de ser enviados e é hora de se preparar para enviar o bit de parada.
Portanto, PIN_TXD = 1, a porta de envio é atribuída diretamente ao nível alto.
A última décima interrupção representa que o bit de parada também foi enviado.Portanto, cnt reset recebe um valor 0, TR0 recebe um valor 0, o temporizador 0 é desligado, TXDEnd = 1, o sinalizador de final de transmissão é definido como 1 e a transmissão de um quadro de dados completo é concluída.
Depois dissomódulo receptor: Enviamos 0xAA anteriormente para esta função, seu valor é o resultado da adição de 1 aos dados recebidos, então os dados recebidos são: 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; //置接收结束标志
- }
- }
- }
Pode-se observar que os processos de envio e recebimento são realmente semelhantes. Para o recebimento de dados, marquei a primeira interrupção como começando no horário 0, principalmente para cooperar com o cnt para facilitar o entendimento.
Conforme mostrado na figura, você pode ver que o tempo que leva para entrar na interrupção pela 0ª vez é metade do tempo de interrupção predefinido. Isso ocorre porque ao confirmar se um sinal de nível é 0 ou 1, se o nível for o mais cedo. O tempo de amostragem pode ocorrer erro ou interferência, então o ponto de amostragem é geralmente definido no ponto médio do tempo de transmissão do sinal, e o sinal de nível ali é considerado o sinal transmitido neste período de tempo. Portanto, o módulo receptor só precisa definir seu tempo de interrupção para metade do original quando recebe o bit de início pela primeira vez, de modo a garantir que todos os pontos de coleta de sinal subsequentes estejam no ponto central.
Vejamos como o programa está configurado: TL0 = 256 - ((256-TH0) >> 1); //Aceita que o tempo T0 é metade do período da taxa de transmissão ao iniciar;
256-TH0 é o tempo de interrupção predefinido. Como mencionamos antes, esperamos que o tempo de interrupção seja metade do anterior. A operação do programa é deslocá-lo para a direita em 1 bit. de 8. Deslocar 1 para a direita é 0000 0100 = 4. Pode-se ver que a operação de deslocar 1 bit para a direita é alterar o número para metade do valor original. Da mesma forma, o resultado do deslocamento de 1 bit para a esquerda é 0001 0000 =16, o que significa multiplicar o número original por 2
Iniciar análise do processo do programa
Quando RxdorTxd for 0, insira a função else, ou seja0ª vez Entrando na interrupção, o ponto inicial do módulo receptor no domínio do tempo é o ponto médio do bit inicial. Primeiro determine se a tensão da porta está realmente baixa e, caso contrário, desligue a interrupção. Por que fazer isso?
Por se tratar de um módulo receptor, a tensão do RXD não é controlada pelo microcontrolador. Neste caso, é controlada pelo computador que controla a tensão do terminal TXD do CH340T. A tensão do RXD do microcontrolador segue a extremidade CH340TXD. Para a extremidade receptora, a informação recebida pode sofrer interferência e precisa ser confirmada novamente.
Se sim, cnt++, então cnt=1. RxdBuf = 0; limpe o buffer de recebimento para 0;
Depois disso1º(na verdade, pela segunda vez)Segunda categoria Insira a interrupção cnt = 1 e insira a função else if() para transferir dados para o buffer passo a passo. O processo subsequente não será descrito em detalhes se os leitores interessados puderem realizá-lo sozinhos, de acordo com a lógica do programa. Veja se os dados podem realmente ser armazenados na variável buffer primeiro com bits baixos e depois com bits altos. Porque na postagem anterior do blog, a função usa o método left shift para primeiro armazenar os bits altos dos dados. Esta abordagem complementa bastante outra forma de trabalhar.
Neste ponto, o programa usa o temporizador 0 para simular a comunicação serial UART.
Três tipos básicos de comunicação
Comunicação simplex: Apenas uma parte pode transmitir informações à outra parte, e a outra parte não pode enviar informações de volta, como controles remotos de TV, transmissões de rádio, etc.
Comunicação half-duplex: os dados podem ser transmitidos entre duas partes e apenas uma parte pode enviá-los para a outra parte ao mesmo tempo. Por exemplo, um walkie-talkie é uma comunicação half-duplex típica. O programa de simulação de porta serial acima também pode ser entendido como comunicação half-duplex
Comunicação full-duplex: os dados podem ser enviados ao mesmo tempo que se recebem dados, e os dois são realizados simultaneamente, como a nossa comunicação telefônica.
A comunicação serial de simulação de porta IO mostra basicamente a essência da comunicação serial, mas o programa do microcontrolador precisa detectar e escanear constantemente os dados recebidos pela porta IO do microcontrolador, o que ocupa muito tempo de execução do microcontrolador. Portanto, existe um módulo UART dentro do microcontrolador 51, que pode receber dados automaticamente, bastando notificá-los após recebê-los. Para utilizá-los corretamente, é necessário configurar corretamente o registro de função especial.
Registro de controle serial SCON
Este caso introduz apenas o modo 1, ou seja, configurar SM1 = 1 e SM0 = 0 é o modo 1. Este modo é o formato do quadro de dados usado na comunicação serial simulada anterior: 1 bit de início, 8 bits de dados e 1 bit de parada.
A comunicação serial analógica usa o temporizador 0 para expressar a taxa de transmissão O transmissor de taxa de transmissão do módulo UART STC89C52 só pode ser gerado pelo temporizador T1 ou T2, mas não pelo temporizador T0.
Ao usar o temporizador T2, são necessários registros de configuração adicionais. Por padrão, o temporizador T1 é usado.
Código do programa:
- # 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发送中断标志位
- }
-
- }
Confira o vídeo dos resultados:Vem com módulo de comunicação serial_bilibili_bilibili
Percebe-se que a comunicação normal pode ser alcançada sem nenhum problema, e a seguir é dada uma breve explicação do conteúdo relevante do programa:
A fórmula de cálculo para o valor de recarga do temporizador T1 é:
TH1 = TL1 = 256 - valor do oscilador de cristal/12/2/16/taxa de transmissão então é
Tempo de intervalo de interrupção = valor do oscilador de cristal/12/2/16/taxa de transmissão = valor do oscilador de cristal/12*(1/taxa de transmissão)*(1/32)
Valor do oscilador de cristal/12 significa o número de ciclos da máquina em 1 segundo, (1/taxa de transmissão) significa o tempo necessário para transmitir 1 bit de dados
Valor do oscilador de cristal/12* (1/taxa de transmissão) significa quantos processadores de máquina são necessários para transmitir 1 bit de dados
Da mesma forma, o valor do oscilador de cristal/12*(1/taxa de transmissão)*(1/32) o tempo desta interrupção = 1/32 do tempo para transmitir 1 bit de dados
Ou seja, a transferência de 1 bit de dados é dividida em 32 intervalos de tempo.
O resultado calculado é 3, ou seja, o intervalo de interrupção = 3 ciclos da máquina. Este tempo é muito curto.
Porque o método de amostragem de sinal do módulo de porta serial é coletar um único sinal 16 vezes e retirar os níveis de sinal da 7ª, 8ª e 9ª vezes. Se duas das três vezes forem níveis altos, os dados são considerados como. seja 1. Se o nível for 0 duas vezes, este bit é considerado 0. Desta forma, se os dados forem lidos incorretamente devido a interferências inesperadas, a exatidão dos dados finais ainda poderá ser garantida.
A imagem abaixo é de uma postagem de blog recomendada, principalmente para facilitar a explicação.: Fórmula de cálculo da taxa de transmissão
SMOD é controlado pelo registro de potência PCON. Por padrão, SMOD é 0. Substituindo-o na fórmula acima está a fórmula de solução de valor inicial anterior.
TH1 = TL1 = 256 - valor do oscilador de cristal/12/2/16/taxa de transmissão
Quando o valor mais alto do registro é definido como 1 PCON |= 0x80; ou seja, SMOD é definido como 1, a taxa de transmissão pode ser duplicada, conforme mostrado na fórmula acima.
Neste momento, o valor inicial de T1 torna-se: TH1 = TL1 = 256 - valor do oscilador de cristal/12/16/taxa de transmissão
Uma coisa que deve ser observada aqui é que: Se você quiser usar o registro PCON para controlar a taxa de onda para dobrar, sua fórmula de valor inicial ainda precisa ser escrita como
TH1 = TL1 = 256 - valor do oscilador de cristal/12/2/16/taxa de transmissão é apenas
O valor de recarga atual é TH1=256 - (11059200/12/32)/baud =256-(11059200/12/16)/(2*buad) baud*2=4800*2=9600, 9600 é o valor do taxa de transmissão do programa atual
Se sua empresa de recarga de valor inicial escrever TH1 = TL1 = 256 - valor do oscilador de cristal/12/16/taxa de transmissão, então sua taxa de transmissão atual ainda é 4800, não 9600.Você usa o software de comunicação serial para definir a taxa de transmissão de comunicação para 9600 e ele transmiteO resultado está errado。
Assista o vídeo:Taxa de transmissão relacionada_bilibili_bilibili
Podemos ver que o intervalo de tempo para a taxa de transmissão de 9.600 é de apenas 3 ciclos de máquina, e o intervalo de tempo de 14.400 é de 2 ciclos de máquina. Pode-se observar que se sua taxa de transmissão for maior, seu intervalo de tempo pode ser menor que 1 ciclo de máquina. Portanto, existe outro modo de funcionamento, ou seja, ConfigUART(9600) após o bit mais alto do PCON ser definido como 1, sua taxa de transmissão atual é 19200, mas seu intervalo de tempo é o intervalo de tempo da taxa de transmissão original de 9600, que é; 3 ciclos de máquina.
Deve-se lembrar que ainda existem muitas diferenças no funcionamento do temporizador 0 de comunicação serial simulada e do módulo de comunicação serial. O módulo de comunicação serial completa uma entrada e uma saída, e entra apenas em duas interrupções de comunicação serial. Uma vez em resposta ao RI ser definido como 1, uma vez em resposta ao TI ser definido como 1 e, em seguida, apagado pelo software. Não preste mais atenção ao processo de transmissão, concentre-se apenas em saber se a transmissão foi concluída e envie um sinal quando a transmissão for concluída.
O circuito de envio e recebimento da comunicação serial possui fisicamente dois registradores SBUF idênticos, e seus endereços também são 0x99, mas um é usado para enviar buffer e o outro é usado para receber buffer. Isso significa que há dois quartos e os números das casas dos dois quartos são iguais. Um deles pode entrar, mas o outro não pode sair, mas não pode entrar. Desta forma, a comunicação full-duplex do UART pode ser alcançada sem interferência entre si. Mas logicamente, apenas o SBUF é operado de cada vez, e o microcontrolador escolhe automaticamente se deseja receber o SBUF ou enviar o SBUF com base no fato de executar uma operação de “leitura” ou “gravação” nele.
Etapas básicas do programa de comunicação serial:
1. Configure a porta serial para modo 1.
2. Configure o temporizador T1 para o modo 2, que é o modo de reinstalação automática.
3. Calcule os valores iniciais de TH1 e TL1 com base na taxa de transmissão. Se necessário, você pode usar o PCON para dobrar a taxa de transmissão.
4. Abra o registro de controle do temporizador TR1 e deixe o temporizador funcionar.Nota: Ao usar a interrupção da porta serial, a interrupção do temporizador 1 não poderá mais ser habilitada, a menos que você esteja usando a interrupção da porta serial do temporizador 2.