The terminal is a cool thing, but sometimes the app is more handy thing to use, plus it simply more attractive than a blank black window. At the moment I was exploring C++ Builder and decide to make a simple GUI for my devboard, so I can control it from my PC.
So, what steps should we walk to make it happen?
- Write/find/dig the source for a program for COM port communications
- Write the uC code
- Make the more or less attractive GUI
The first step was the most complicated for me, my knowledge of C++ was not sufficient, so I was researching the web. Finally, I landed on the website – http://piclist.ru/S-COM-THREAD-RUS/S-COM-THREAD-RUS.html, where I found not just code but also some GUI template for my first app.
Now, time to go to the uC code:
#include <stdio.h> #include <htc.h> #define _XTAL_FREQ 4000000 #include "usart.h" __CONFIG(LVPDIS & WDTDIS & MCLREN & UNPROTECT & HS); void main(void){ unsigned char input; TRISB4 = 0; TRISB6 = 0; TRISB7 = 0; TRISB5 = 0; INTCON=0; // purpose of disabling the interrupts. init_comms(); // set up the USART - settings defined in usart.h RB4 = 0; RB5 = 0; RB6 = 0; RB7 = 0; for (;;) { input = getch(); switch (input) { case 49 : RB4 = !RB4; break; case 50 : RB5 = !RB5; break; case 51 : RB6 = !RB6; break; case 52 : RB7 = !RB7; break; } } }
The code is quite simple – the infinite cycle, waiting to spot symbols 1, 2, 3 or 4 and if it happened, change the LED state to inverse one.
What is left to do – to polish the GUI for my particular application. Since the app is just serving my learning purposes, I made it straightforward and simple – the area of COM initialization procedure and the LEDs area. Below, my additional strings to the sources from the piclist.ru website (the WINAPI version):
void __fastcall TForm1::CheckBox3Click(TObject *Sender) //галочка L4 { if (Form1->CheckBox3->Checked == true) { memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"1"); //занести в программный передающий буфер 1 ResumeThread(writer); //активировать поток записи данных в порт Label7->Caption="1"; } else { Label7->Caption="0"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"1"); //занести в программный передающий буфер 1 ResumeThread(writer); //активировать поток записи данных в порт } } void __fastcall TForm1::CheckBox4Click(TObject *Sender) //галочка L5 { if (Form1->CheckBox4->Checked == true) { Label8->Caption="1"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"2"); //занести в программный передающий буфер 2 ResumeThread(writer); //активировать поток записи данных в порт } else { Label8->Caption="0"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"2"); //занести в программный передающий 2 ResumeThread(writer); //активировать поток записи данных в порт } } void __fastcall TForm1::CheckBox5Click(TObject *Sender) //галочка L6 { if (Form1->CheckBox5->Checked == true) { Label9->Caption="1"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"3"); //занести в программный передающий буфер 3 ResumeThread(writer); //активировать поток записи данных в порт } else { Label9->Caption="0"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"3"); //занести в программный передающий буфер 3 ResumeThread(writer); //активировать поток записи данных в порт } } void __fastcall TForm1::CheckBox6Click(TObject *Sender) //галочка L7 { if (Form1->CheckBox6->Checked == true) { Label10->Caption="1"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"4"); //занести в программный передающий буфер 4 ResumeThread(writer); //активировать поток записи данных в порт } else { Label10->Caption="0"; memset(bufwr,0,BUFSIZE); //очистить программный передающий буфер, чтобы данные не накладывались друг на друга PurgeComm(COMport, PURGE_TXCLEAR); //очистить передающий буфер порта strcpy(bufwr,"4"); //занести в программный передающий буфер 4 ResumeThread(writer); //активировать поток записи данных в порт } }
Messy, messy stuff, but it works:
Pingback: Pic Lab, PIC16, Experiment #19, The WIN QT application for COM port | diymicro.org