-
1 # 易學微控制器
-
2 # 果樂果菓
你所說的控制是指那種方式呢?是控制每一步的執行方式?例如線上模擬,程式內設定斷點,檢視執行時變數的數值變化。還可以和微控制器進行通訊,如使用串列埠,CAN,乙太網等通訊方式和微控制器進行資料互動,讀取微控制器採集的資訊,也可以向單片機發送指令,控制微控制器。這就需要看微控制器的應用場景了。初學者還可以使用Proteus軟體進行模擬除錯。這是一款集模擬、原理圖,PCB設計於一體的軟體。對於微控制器初學者來說,該軟體非常實用,不需要你有硬體電路即可透過模擬學習微控制器的程式設計。
-
3 # 老馬識途微控制器
個人電腦可以透過微控制器模擬軟體、USB介面、串列埠、網口、無線、藍芽等方式控制微控制器。
首先要說的一點是:想要實現個人電腦控制微控制器,首先要讓微控制器“願意”被控制,這個“願意”是指微控制器程式裡面有能夠接受外部控制指令的功能,這樣才能實現,否則微控制器就不能被控制。
一、透過微控制器模擬軟體控制微控制器關於這種方式,我在“如何線上實時監控除錯微控制器程式執行”這個問答裡已經有過說明了,大家感興趣的話,可以去看看。這裡就不多說了。
二、透過USB口或串列埠控制微控制器個人電腦要實現透過USB口或串列埠控制微控制器,首先要確保微控制器電路板上有USB或者串列埠介面,並且還需要微控制器程式裡面有透過USB或者串列埠控制微控制器的功能程式。
在這種條件下,個人電腦可以用過USB連線、串列埠連線、USB轉串列埠連線等方式與微控制器建立起通訊機制,並且此時個人電腦要傳送微控制器能夠“聽懂”的話才行,也就是個人電腦和微控制器雙方要遵循一定的通訊機制,例如雙方事先規定好個人電腦傳送“1”表示要讓LED燈亮,那麼微控制器接收到這個“1”後,才會點亮LED。
三、透過網路介面控制微控制器這種方式需要微控制器電路板上有一個網路模組,然後電腦要連到這個網路模組所在的網路上,這樣才能夠實現個人電腦控制微控制器,一般情況下單片與網路模組的的連結是透過串列埠連線的,這樣就比較簡單了。
但是現在的ARM等都帶有網路介面,這樣就不需要網路模組了,不過相應的就需要較為複雜的程式編寫。
四、透過無線、藍芽方式控制微控制器這種方式需要微控制器電路上連線有無線、藍芽模組。而計算機也需要連線無線、藍芽模組。
對於本身具有無線或藍芽功能的微控制器,只需要編寫複雜的相應通訊程式。而對於只需透過串列埠連線的已經做好協議的藍芽或無線通訊模組,只需要根據指令編寫串列埠通訊程式就可以了。
-
4 # 技術閒聊
電腦控制微控制器,那麼電腦和微控制器之間必須通訊。兩個裝置之間的通訊方式有很多種,常用的有RS232、RS485、RS422、USB、CAN、乙太網、藍芽、WIFI等通訊方式。
要使用某一通訊方式,微控制器和電腦必須具有相應的通訊介面,個人電腦一般有RS232、USB、乙太網、藍芽等通訊方式。
假設使用RS232通訊,電腦自帶有RS232介面,無需擴充套件,那麼微控制器硬體必須設計有RS232介面,使用RS232延長線連線即可,接下來就是編寫軟體了,包括底層驅動程式,以實現電腦控制微控制器,比如使用C++、C#等編寫人機互動介面,定義通訊協議,編寫底層驅動,即可實現透過自己編寫的人機互動介面控制微控制器。如果只是簡單的控制也可以使用串列埠除錯助手直接給單片機發送命令,以達到控制微控制器的目的。
也可以使用其他通訊方式,比如RS485、RS422、USB、CAN、乙太網、藍芽、WIFI等都可以使用,但是微控制器必須擴充套件相應的通訊介面,如電腦沒有相應的通訊介面,可以購買相應的通訊轉換器即可,比如使用CAN通訊,只需購買一個USB轉CAN的轉換器即可,USB直接連線電腦,轉換器CAN介面與微控制器CAN介面相連。
使用WIFI、藍芽通訊方式,可以實現手機直接控制微控制器,編寫一個控制微控制器的手機APP軟體,配置好WIFI或藍芽協議,手機APP傳送一個命令,透過手機WIFI或藍芽將資訊傳輸至微控制器WIFI或藍芽接收端,從而實現了手機直接控制微控制器。WIFI或藍芽模組可以直接淘寶上購買現成的也不貴。
-
5 # sharpxcb
微控制器就如同一臺沒有系統的小電腦,主電腦想跟這臺小電腦怎麼連,就在這臺小電腦上新增什麼外設:網絡卡(有線、WIFI)、USB(轉換晶片)、串列埠均可,再新增對應驅動(上行編碼下載解碼對應程式),空間夠大、資源夠多的跑個小系統也未嘗不可!
-
6 # IT自動化交流
個人電腦控制微控制器,主要透過以下步驟:1)建立個人電腦和微控制器的通訊連線
普通的微控制器通常有UART、SPI、IIC、USB等通訊模組。
和電腦通訊最常用的是UART,可以有兩種方式和電腦建立連線(現在的膝上型電腦很少有支援RS232的DB9介面,所以需要使用USB轉TTL,或者USB轉485的資料線):
從網上購買USB轉TTL的串列埠線:
透過UART-TTL,將微控制器的串列埠TX,RX引出,加限流保護電阻之後,將串列埠線的地和微控制器的地接到一起,將微控制器的串列埠TX接到串列埠線的RX,將微控制器的串列埠RX接到串列埠線的TX。
還可以透過RS485匯流排與電腦連線;
仍然從網上購買USB轉RS485的資料線:
RX,TX,以及傳送/接收使能控制腳如下圖連線至485晶片(如MAX485),將微控制器的串列埠轉成485匯流排。
除了串列埠之外,還可以從網上購買支援UART介面的乙太網模組或者wifi模組。
透過乙太網模組,或者wifi模組內建的TCP/IP協議棧,採用TCP/IP通訊與個人電腦建立連線。
微控制器與模組之間的控制(如初始化、建立TCP客戶端/服務端,傳送/接收TCP/UDP報文等)可以透過標準的AT指令實現。
2)制定協議以及編寫軟體如果是透過RS485連線,建議採用MODBUS通訊協議。
個人自定義協議,我通常採用如下格式:
1位元組幀頭,2位元組資料長度,1位元組命令字,n位元組payload,1位元組crc8校驗
包括微控制器軟體和上位機軟體,
不管是串列埠/RS485通訊,還是TCP/IP通訊,都是微控制器串列埠的通訊程式。
包括髮送和接收程式,一般開闢傳送/接收兩塊快取,在串列埠中斷接收程式中,將串列埠接收到的資料放在環行佇列,在主程式中根據協議從環行佇列中取出資料進行解析,當解析到有效資料之後,再拋給應用層程式進行相關處理(如IO口控制,IO口讀取,FLASH讀寫等)。
當應用層需要傳送資料時,請求串列埠傳送,將資料填入傳送快取,之後串列埠程式串列埠傳送中斷程式中將資料逐位元組送入串列埠傳送暫存器。
以下是我在產品中實際使用的串列埠程式。
#include "Uart.h"
#include "IO.h"
#include "crc.h"
#include "Timer.h"
#include "Strs.h"
#include "WiFi.h"
#define P_UA_TX_P GPIOA
#define P_UA_TX_V 9
#define P_UA_RX_P GPIOA
#define P_UA_RX_V 10
#define UART_WIFI ((USART_TypeDef *) USART1_BASE)
STRUARecType g_ua_stRecRegs;
STRUASendType g_ua_stSendRegs;
#define ENABLE_UART_TX() {\
UART_WIFI->CR1 |= USART_CR1_TXEIE;\
}
//禁止傳送中斷,使能接收
#define DISABLE_UART_TX() {\
UART_WIFI->CR1 &= ~USART_CR1_TXEIE;\
g_ua_stSendRegs.m_uchSendTimer = 0;\
}
#define ENABLE_UART_INT() {\
NVIC_EnableIRQ(USART1_IRQn);\
}
void fnUA_Init(void);
void fnUA_RealTime(void);
void fnUA_IOInit(void);
void fnUA_RegInit(void);
void fnUA_IOInit(void)
{
//使能外設時鐘
U16 bandrate;
SET_IO_AFMODE_PP(P_UA_TX_P, P_UA_TX_V);
SET_IO_IN_WITHOUTPULLUP(P_UA_RX_P, P_UA_RX_V);
//復位UART1外設模組
RCC->APB2RSTR |= RCC_APB2RSTR_USART1RST;
RCC->APB2RSTR &= ~RCC_APB2RSTR_USART1RST;
//使能外設時鐘
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
//使能UART功能
UART_WIFI->CR1 = 0; //OVER8=0:16bit sample;M=0:8data bits;PCE=0:parity disable;
UART_WIFI->CR2 = 0; //ABREN=0:Auto baud rate detection is disabled;one stop bit;
UART_WIFI->CR3 = 0; //OVRDIS=0: Overrun enable;ONEBIT=0: Three sample bit method;EIE=0: Error interrupt enable
// 24M FCK 配置波特率為19200U; 24000000/19200=1250(0x04e2)
bandrate = ((U32)SYSCLK_SYS_FREQ / 2 / (U32)115200);
UART_WIFI->BRR = bandrate;//);
UART_WIFI->SR |= (USART_SR_PE |USART_SR_FE|USART_SR_NE |USART_SR_ORE|USART_SR_TC);
//接收/接收中斷使能
UART_WIFI->CR1 |= USART_CR1_RE | USART_CR1_RXNEIE;
//傳送使能
UART_WIFI->CR1 |= USART_CR1_TE ; //TCIE = 0;TXEIE = 0;IDLEIE = 0;
//使能UART外設模組
UART_WIFI->CR1 |= USART_CR1_UE;
ENABLE_UART_INT();
}
void fnUA_RegInit(void)
{
memset(&g_ua_stRecRegs, 0, sizeof(g_ua_stRecRegs));
memset(&g_ua_stSendRegs, 0, sizeof(g_ua_stSendRegs));
}
void fnUA_Init(void)
{
fnUA_RegInit();
fnUA_IOInit();
}
void USART1_IRQHandler(void)
{
unsigned char temp =0;
static U8 crc = 0;
//Receive Int
if(UART_WIFI->CR1 & USART_CR1_RXNEIE)
{
while(UART_WIFI->SR & USART_SR_RXNE)
{
temp = UART_WIFI->DR;
g_ua_stRecRegs.m_uchRingBuff[g_ua_stRecRegs.m_uchInP & (UA_RX_RINGBUFF_SIZE - 1)] = temp;
g_ua_stRecRegs.m_uchInP++;
}
}
//Transmitter Int
if(UART_WIFI->CR1 & USART_CR1_TXEIE)
{
if(UART_WIFI->SR & USART_SR_TXE)
{//UART傳送中斷
if(g_ua_stSendRegs.m_uchIsSending)
{
if(0 == g_ua_stSendRegs.m_uchIndex)
{
crc = 0;
}
if(g_ua_stSendRegs.m_uchIndex < g_ua_stSendRegs.m_uchCount)
{
temp = g_ua_stSendRegs.m_uchBuff[g_ua_stSendRegs.m_uchIndex];
if(g_ua_stSendRegs.m_uchIndex == (g_ua_stSendRegs.m_uchCount - 1))
{
temp = crc;
}
else
{
crc += temp;
}
UART_WIFI->DR = temp;
g_ua_stSendRegs.m_uchIndex ++;
}
else
{
DISABLE_UART_TX();
g_ua_stSendRegs.m_uchIsSending = FALSE;
}
}
}
}
}
#define UA_RX_CHARTIME 8
void fnUA_RecMsg(void)
{
U16 outp;
U8 temp;
static U8 crc = 0;
if(g_tm_stTimerFlag.Bits.bTimer16ms)
{
if(g_ua_stRecRegs.m_uchCharTime)
{
g_ua_stRecRegs.m_uchCharTime--;
if(0 == g_ua_stRecRegs.m_uchCharTime)
{
g_ua_stRecRegs.m_uchPointer = 0;
}
}
}
if(FALSE == g_ua_stRecRegs.m_uchReceived)
{
while(g_ua_stRecRegs.m_uchInP != g_ua_stRecRegs.m_uchOutP)
{
outp = g_ua_stRecRegs.m_uchOutP & (UA_RX_RINGBUFF_SIZE - 1);
g_ua_stRecRegs.m_uchOutP++;
temp = g_ua_stRecRegs.m_uchRingBuff[outp];
if(0 == g_ua_stRecRegs.m_uchPointer)
{
if(0x55 == temp)
{
crc = 0;
g_ua_stRecRegs.m_uchPointer = 1;
}
}
else if(1 == g_ua_stRecRegs.m_uchPointer)
{
if(0xFF == temp)
{
g_ua_stRecRegs.m_uchPointer = 2;
}
else if(0x55 != temp)
{
g_ua_stRecRegs.m_uchPointer = 0;
}
}
else if(g_ua_stRecRegs.m_uchPointer <= 3)
{
g_ua_stRecRegs.m_uchBuff[g_ua_stRecRegs.m_uchPointer - 2] = temp;
g_ua_stRecRegs.m_uchLen = 0;
g_ua_stRecRegs.m_uchPointer ++;
}
else if(g_ua_stRecRegs.m_uchPointer <= 5)
{
g_ua_stRecRegs.m_uchLen = g_ua_stRecRegs.m_uchLen << 8;
g_ua_stRecRegs.m_uchLen |= (U16)temp;
g_ua_stRecRegs.m_uchBuff[g_ua_stRecRegs.m_uchPointer - 2] = temp;
g_ua_stRecRegs.m_uchPointer ++;
if(g_ua_stRecRegs.m_uchLen >= (UA_RX_BUFF_SIZE - 5)) //msgid, length;
{
g_ua_stRecRegs.m_uchPointer = 0;
}
}
else
{
g_ua_stRecRegs.m_uchBuff[g_ua_stRecRegs.m_uchPointer - 2] = temp;
g_ua_stRecRegs.m_uchPointer++;
if(g_ua_stRecRegs.m_uchPointer >= (g_ua_stRecRegs.m_uchLen + 7))
{
g_ua_stRecRegs.m_uchPointer = 0;
if(crc == temp)
{
g_ua_stRecRegs.m_uchRecvTimer = 6;
g_ua_stRecRegs.m_uchLen += 5;
fnWF_ResetDeadTime();
g_ua_stRecRegs.m_uchReceived = TRUE;
}
break;
}
}
crc += temp;
}
}
}
void fnUA_Monitor(void)
{
if(g_tm_stTimerFlag.Bits.bTimer16ms)
{
if(g_ua_stSendRegs.m_uchSendTimer)
{
g_ua_stSendRegs.m_uchSendTimer --;
if(0 == g_ua_stSendRegs.m_uchSendTimer)
{
fnUA_Init();
}
}
}
}
void fnUA_RealTime(void)
{
U32 data;
fnUA_Monitor();
fnUA_RecMsg();
if(g_tm_stTimerFlag.Bits.bTimer100ms){
if(g_ua_stRecRegs.m_uchRecvTimer)
{
g_ua_stRecRegs.m_uchRecvTimer--;
if(0 == g_ua_stRecRegs.m_uchRecvTimer)
{
g_ua_stRecRegs.m_uchReceived = FALSE;
}
}
}
}
U8 fnUA_SendReq(U16 msgid, U16 len)
{
U8 res = FALSE;
g_ua_stSendRegs.m_uchBuff[0] = 0x55;
g_ua_stSendRegs.m_uchBuff[1] = 0xFF;
g_ua_stSendRegs.m_uchBuff[2] = (U8)(msgid >> 8);
g_ua_stSendRegs.m_uchBuff[3] = (U8)msgid;
g_ua_stSendRegs.m_uchBuff[4] = (U8)(len >> 8);
g_ua_stSendRegs.m_uchBuff[5] = (U8)len;
g_ua_stSendRegs.m_uchCount = len + 7;
g_ua_stSendRegs.m_uchSendTimer = (200);
g_ua_stSendRegs.m_uchIndex = 0;
g_ua_stSendRegs.m_uchIsSending = TRUE;
ENABLE_UART_TX();
res = TRUE;
return(res);
}
U8 fnUA_IsSend(void)
{
U8 res = TRUE;
if(FALSE == g_ua_stSendRegs.m_uchIsSending)
{
res = FALSE;
}
return res;
}
簡單的除錯,可以用串列埠除錯工具,採用MODBUS協議的工業控制可以用wincc等組態軟體。
對於上位機軟體,需要選擇整合開發環境和程式語言。
這裡選擇非常多,可以用C語言的VC, PASCAL語言的delphi,指令碼語言python,甚至可以用圖形化程式語言labview.
我個人比較喜歡用delphi,接下來講一下delphi的程式設計實現。
先在delphi上設計人機介面,比如下圖的介面。
採用MSCOMM或者SPCOMM實現串列埠通訊。
根據使用者的操作傳送資料給微控制器,接收微控制器的資料顯示在介面上,有些基本需要透過資料庫控制元件,採用access或者mysql資料庫,將採集到的資料儲存下來。
-
7 # 電子產品設計方案
個人電腦控制微控制器要建立上位機和下位機的通訊連線
電腦(計算機)我們定義為上位機,微控制器定義為下位機;兩者之間可以透過串列埠或者USB進行連線通訊;比較老的電腦還有並口,現在基本上已經沒有了。
串列埠連線通訊一般的微控制器都有UART介面,可以和電腦的串列埠進行通訊。
因為電腦的串列埠使用的是RS232電平,電平訊號是+/-12V;而微控制器的UART使用的是TTL電平,電平訊號是5V(或者3.3V)。兩者是沒辦法直接溝通的,需要用到232晶片來進行“翻譯”
經過轉換的訊號就可以通訊了。電腦串列埠的Rx(接收)要接到微控制器的Tx(傳送),電腦串列埠的Tx(傳送)要接到微控制器的Rx(接收);一邊發,另一邊就是收。
電腦沒有串列埠怎麼辦?現在新的電腦,特別是筆計本,很多都取消了串列埠,那怎麼辦呢?我們可以使用USB轉TTL的模組來進行轉換
USB轉UART的模組的Rx接到微控制器的Tx;Tx接到微控制器的Rx就要以了;
USB直接通訊功能比較強大的微控制器,還有USB介面,可以連線電腦的USB介面進行通訊
硬體連線通了,還需要通訊程式配合電腦和微控制器都需要執行適當的程式才可以互相收發資料。就好比水管接好了,也需要有水的配合才可以哦。
回覆列表
透過串列埠通訊
串列埠通訊主要用於實現系統之間的連線和資料交換。底層連線也就是硬體連線要基於序列介面來實現,上層協議需要我們自己分析和制定,透過軟體程式設計實現。
硬體連線通訊協議軟體程式編寫主要是設定波特率、串列埠工作方式、資料位數、是否有校驗位等引數,在傳送端按位傳送,接收端按位接收,通訊協是保障通訊雙方正確接收資料的保證。
比方說軟體(晶振11.0592MHZ)編寫中串列埠初始化:
SCON=0x50; //10位資料 1位起始位 8位資料位 1位停止位
TMOD|=0x20;
TH1=0xfd; // 波特率9600bps
TL1=0xfd;
TR1=1;
IE|=0x10;
那麼上位機串列埠終端就同一樣要保持一致,才能保證正常收發。
控制實現上位機(電腦)傳送指令,微控制器接收後解析,然後根據解析到的指令執行相關控制任務。