
پروژه کنترل شدت نور و ارتباط بی سیم با میکروکنترلر avr – قسمت سوم
درقسمت های قبلی با قسمت های مختلف و شرح کار دستگاه مد نظر آشنا شدیم . حال در این قسمت بصورت جز به جز به شرح نرم افزاری مدار و برنامه نویسی میکروکنترلر می پردازیم.
شماتیک سخت افزاری مدار

برنامه نویسی و نرم افزار های مورد استفاده:
جهت برنامه نویسی میکروکنترلر و پروگرام کردن میکرو از نرم افزار کد ویژن استفاده شده این نرم افزار در کنار کاربری آسان به خوبی از زبان برنامه نویسی محبوب سی پشتیبانی میکند.
اپلیکیشن و نرم افزار مورد استفاده که کاربر باید بر روی گوشی خود داشته باشد نرم افزار ترمینال بلوتوث (Bluetooth terminal) است؛ با این نرم افزار میتوانید با ماژول بلوتوث hc-05 ارتباط برقرار کنید و کد ها و دستورات خود را برای آن ارسال کنید.
برای مثال ما در اینجا دستورات را بصورت زیر در نظر گرفتیم:
#Lx:ab
به این صورت ک x یک عدد بین ۱ تا ۴ است به معنی شماره لامپ و a,bهم یک عدد دورقمی جهت تنظیم شدت نور لامپ برای مثال اگر بخواهیم نور لامپ ۲ برابر ۶۰ درصد شود باید دستور زیر را بنویسیم و به میکرو ارسال کنیم:
#L2:60
دقت کنید که بعد از دونقظه حتما باید دو رقم باشد و سیستم را طوری طراحی کردیم که در صورتی که بتواند رشته دریافتی را دیکد کند به شما رشته زیر را به معنی موفقیت در دریافت ارسال میکن:
Read successfully!
اگر بخواهیم روند برنامه نویسی میکروکنترلر را بصورت کلی بنویسیم مانند خطوط زیر است:
۱-شروع
۲- تنظیم پورت های خروجی
۳-تنظیم رجیستر های مربوط به یوزارت
۴-تنظیم نمایشگر کاراکتری( جهت مشاهده اینکه پیام دریافت شده و اینکه نور لامپ ها چند درصد است)
۵-تنظیم و تعریف متغییر هایی جهت ذخیره عرض پالسه به نام L1,L2,L3,L4
۶-تنظیم اولیه pw تمام پالسا با مقدار ۵۰ درصد
۷-مقدار نور پالسها را با توجه مقدار متغییر L1,L2,L3,L4 تنظیم کن
۸-اگر در بافر وقفه دریافت تغییراتی صورت داده آن را بخوان در غیر این صورت برو مرحله ۷
۹- متغییر بافر ارتباط سریال:مقدار جدید دریافتی را بخوان و مقادیر را در L1,L2,L3,L4 ذخیره کن.
۱۰- برو به مرحله ۷
حال به شرح توابع و متغییرهای بکار رفته می پردازیم:
آرایه نگهدارنده رشته دریافتی:
unsigned char Rx_buffer[RX_BUFF_SIZE];
آرایه نگهدارنده میزان عرض پالسها با مقدار اولیه ۵۰:
unsigned char input[4]={50,50,50,50};
از این متغییر برای جستجو در رشته ها استفاده شده و محل آخری رشته را پیدا کردیم در این متغییر ذخیره میکنیم:
unsigned char pos_of_srch_res=0;
متغییری جهت اینکه بدانیم الان کدام خانه از رشته دریافتی باید مقدار قرار دهیم:
unsigned char index=0;
یک متغییر کلی جهت استفاده در حلقه ها:
int i=0;
لیست کلی توابع:
تابع تنظیم مقدار عرض پالسها که منجر به تنظیم میزان شدت نور هر لامپ میشود. این تابع ۴ مقدار بین ۰ تا ۹۹ می پذرید و با توجه به آن شدت نور تنظیم میشود:
void set_Brightness(char L1,char L2,char L3,char L4);
تابع تنظیمات اولیه پروتکل سریال جهت ارتباطبا ماژول بلوتوٍث.
void USART_init(); //initialize Usart …
تابع ارسال یک کاراکتر به به سریال ( کا این کاراکتر ارسالی به کاربر میرسد):
void USART_send_char(unsigned char data); //send char to USART
تابع جهت ارسال یک رشته به کاربر(این تابه یک رشته را دریافت کرده و با استفاده از تابع بالایی شروع به ارسال کاراکترهای آن رشته میکند):
void USART_send_string(char* str); //send String to UART
تابع وقفه دریافت ( هر گاه کاربر دستوری بفرستد این تابع اجرا میشود و دستورات را کاراکتر به کاراکتر میخواد و در رشته rx_buffer ذخیره میکند):
interrupt [USART_RXC] void usart_rx_interrupt(void);//usart recieved char interrupt…
این تابع طول یک رشته را بر میگرداند:
int get_str_len(char* str);
این تابع یک رشته را دریافت میکند و آن را در رشته rx_buffer جستجو میکند اگر آن را پیدا کرد مقدار ۱ و در غیر این صورت مقدار ۰ را بر میکرداند:
char srch_response_string(char* str);
این تابع مقادیر آرایه input[] را با توجه به دستورات دریافتی تنظیم میکند:
char set_input();
جهت نمایش تغیرات بر روی نمایشگر کاراکتری از این تابع نوشته شده است:
void show_input_in_lcd();
مقادیر رشته rx_buffer را به حروف بزرگ تبدیل میکند:
void set_Rx_buffer_to_upper();
مقدار رشته rx_buffer پاک میکند
void clear_response();
تابع اصلی هر برنامه که به زبان سی باشد:
void main(void);
سورس کامل برنامه:
/*
* Lightness_test.c
*
* Created: 2017/01/06 04:56:41 ب.ظ
* Author: Reza.Ahmadi
* https://mrzx.ir
*/
#include <io.h>
#include <delay.h>
#include <stdio.h> //input and output for usart
#include <stdlib.h> //for convert string to integer
#include <ctype.h> //for using set string to upper case
#asm
.equ __lcd_port=0x1B;//PORTA Addres ...
#endasm
#include <lcd.h>
#define Light1 PORTC.0
#define Light2 PORTC.1
#define Light3 PORTC.2
#define Light4 PORTC.3
#define RX_BUFF_SIZE 128
unsigned char Rx_buffer[RX_BUFF_SIZE];
unsigned char input[4]={50,50,50,50};
unsigned char pos_of_srch_res=0;
unsigned char index=0;
int i=0;
void set_Brightness(char L1,char L2,char L3,char L4);
void USART_init(); //initialize Usart ...
void USART_send_char(unsigned char data); //send char to USART
void USART_send_string(char* str); //send String to UART
interrupt [USART_RXC] void usart_rx_interrupt(void);//usart recieved char interrupt...
int get_str_len(char* str);
char srch_response_string(char* str);
char set_input();
void show_input_in_lcd();
void set_Rx_buffer_to_upper();
void clear_response(){
unsigned char j=0;
for(j=0;j<RX_BUFF_SIZE;j++)
Rx_buffer[j]='';
index=0;
}
void main(void)
{
DDRC=0xff;
PORTC=0x00;
PORTB=0xff;
DDRB=0x00;
lcd_init(16);
lcd_putsf("Hello, System is starting up...");
delay_ms(2000);
USART_init();
delay_ms(1000);
#asm("sei");
USART_send_string("Hello\r\nThis project is designed by: Reza.Ahmadi\r\n");
USART_send_string("Send your structure\r\n");
lcd_clear();
lcd_putsf("send Your structure");
delay_ms(2000);
lcd_clear();
show_input_in_lcd();
while (1)
{
// Please write your application code here
//set_input();
set_Brightness(input[0],input[1],input[2],input[3]);
}
}
void set_Brightness(char L1,char L2,char L3,char L4)
{
char a=1,b=1,c=1,d=1;//store value of ports...
char Lc=0,count=0;
while(1)
{
Light1=a;
Light2=b;
Light3=c;
Light4=d;
delay_us(100);
Lc++;
if(Lc>=L1 && a==1){a=0;}
if(Lc>=L2 && b==1){b=0;}
if(Lc>=L3 && c==1){c=0;}
if(Lc>=L4 && d==1){d=0;}
if(Lc>=100) {Lc=0;a=1;b=1;c=1;d=1;count++;}
if(count>=100 && index>=6)
{
count=0;
if(set_input())
break;
}
}
}
void USART_init()
{
UCSRA=0x00;
UCSRB=0x98;//enable RXD and TXD ,and ENABLE receive INTERRUPT
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33; //set Baud rate to 9600 in fosc 8MHz
}
void USART_send_char(unsigned char data)
{
putchar(data);
}
void USART_send_string(char* str)
{
int len=get_str_len(str);
for(i=0;i<len;i++)
{
USART_send_char(str[i]);
}
USART_send_char('\n');
}
interrupt [USART_RXC] void usart_rx_interrupt(void)
{
char data;
data=UDR;
Rx_buffer[index]=data;
if(++index >= RX_BUFF_SIZE) {index=0;}
}
int get_str_len(char* str)
{
int len=0;
for(i=0;str[i];i++)len=i;
return len+1;
}
char srch_response_string(char* str)
{
unsigned char k=0,start=0;
int len=get_str_len(str);
for(i=0;i<RX_BUFF_SIZE;i++)
{
if(Rx_buffer[i]==str[k])
{k++;start=1;pos_of_srch_res=i;}
else if( start==1 && (Rx_buffer[i] !=str[k]))
{k=0;start=0;}
if(k==len)break;
}
if(k>=len)return 1; // find the str in response msg...
else return 0; // not find
}
char set_input()
{
char temp[2],c=0,acc=0;
set_Rx_buffer_to_upper();
if(srch_response_string("#L1:"))
{
for(i=(pos_of_srch_res+1);i<(pos_of_srch_res+3);i++)
temp[c++]=Rx_buffer[i];
input[0]=atoi(temp);
if(Rx_buffer[pos_of_srch_res+2])
acc=1;
}
c=0;
if(srch_response_string("#L2:"))
{
for(i=(pos_of_srch_res+1);i<(pos_of_srch_res+3);i++)
temp[c++]=Rx_buffer[i];
input[1]=atoi(temp);
if(Rx_buffer[pos_of_srch_res+2])
acc=1;
}
c=0;
if(srch_response_string("#L3:"))
{
for(i=(pos_of_srch_res+1);i<(pos_of_srch_res+3);i++)
temp[c++]=Rx_buffer[i];
input[2]=atoi(temp);
if(Rx_buffer[pos_of_srch_res+2])
acc=1;
}
c=0;
if(srch_response_string("#L4:"))
{
for(i=(pos_of_srch_res+1);i<(pos_of_srch_res+3);i++)
temp[c++]=Rx_buffer[i];
input[3]=atoi(temp);
if(Rx_buffer[pos_of_srch_res+2])
acc=1;
}
if(srch_response_string("#ONALL"))
{
input[0]=99;input[1]=99;input[2]=99;input[3]=99;
acc=1;
}
if(srch_response_string("#OFFALL"))
{
input[0]=0;input[1]=0;input[2]=0;input[3]=0;
acc=1;
}
if(acc==1)
{
clear_response();
USART_send_string("Read successfully!");
show_input_in_lcd();
return 1;
}
return 0;
}
void set_Rx_buffer_to_upper()
{
for(i=0;i<RX_BUFF_SIZE;i++)
Rx_buffer[i]=toupper(Rx_buffer[i]);
}
void show_input_in_lcd()
{
unsigned char strLCD[16];
//lcd_clear();
sprintf(strLCD,">L1:%d >L2:%d ",input[0],input[1]);
lcd_gotoxy(0,0);
lcd_puts(strLCD);
sprintf(strLCD,">L3:%d >L4:%d ",input[2],input[3]);
lcd_gotoxy(0,1);
lcd_puts(strLCD);
}

دیدگاهتان را بنویسید