Results 1 to 2 of 2
Thread: C
Hybrid View
-
28th April 2013 15:37 #1
C
! C, 16x2 LCD AVR . , . .
: , ""/"" (menuscreen) (menuitem). .. :
/Hidden:Code:typedef struct //menuitem { char* text; //the text of the menu item unsigned int line :1; //0 is for the first line, 1 is for the second line unsigned int position :4; //total of 16 possible positions on the LCD volatile int16_t* variable; //variable to be changed struct menuscreen* n_screen; //if the item leads to another menu screen } menuitem; typedef struct //menuscreen { menuitem* choices[6];//the list of elements within a menu screen unsigned int cur_item :3;//the current item selected in the menu } menuscreen;
(menuscreen), menuitem* "main_title", "servo", "speed", "angle", "offset". . , . . : - , - ? , - , . Main (180 ), .
, , "". warnings , "assignment from incompatible pointer type"
, subscript int, .Code://SRV srv.text="SERVO"; srv.line=0; srv.position=5; srv.variable=NULL; srv.n_screen=&menu_servo;// //end SRV
,
/Hidden:Code:/*************MAIN Here we initialize the MAIN menu items*************/ menuitem mainm, srv, spd, angle, offset;// main menu items menu_main.choices[0]=&mainm; menu_main.choices[1]=&srv; menu_main.choices[2]=&spd; menu_main.choices[3]=∠ menu_main.choices[4]=&offset; //MAINM mainm.text="MAIN"; mainm.line=0; mainm.position=0; mainm.variable=NULL; mainm.n_screen=NULL; //end MAINM //SRV srv.text="SERVO"; srv.line=0; srv.position=5; srv.variable=NULL; srv.n_screen=&menu_servo; //end SRV //SPD spd.text="SPEED"; spd.line=0; spd.position=11; spd.variable=NULL; spd.n_screen=&menu_speed; //end SPD //ANGLE angle.text="ANGLE"; angle.line=1; angle.position=0; angle.variable=NULL; angle.n_screen=&menu_angle; //end ANGLE //OFFSET offset.text="OFFSET"; offset.line=1; offset.position=6; offset.variable=NULL; offset.n_screen=&menu_offset; //end OFFSET
/Hidden: 700Code:#include <avr/io.h>#include <stdio.h> #include <stdint.h> #include <util/delay.h> #include <avr/interrupt.h> #include "lcd.h" #include "uart.h" #define F_CPU 20000000UL #define UART_BAUD_RATE 115200 #define HEART 5//Heartbeat is at PD5 #define RSW 7//Rotary Switch 1 is PD7 #define R1 5//Rotary 1 is PD5 #define R2 6//Rotary 2 is PD6 #define SERVO 1//The servo is PB1 //D:\Documents\Dropbox\SOTON\2012-2013\First Semester\ELEC2011 Engineering Design and Manufacture\Programming\LCD inline void switch_init(void); inline void menu_declare(void); typedef struct //menuitem { char* text; //the text of the menu item unsigned int line :1; //0 is for the first line, 1 is for the second line unsigned int position :4; //total of 16 possible positions on the LCD volatile int16_t* variable; //variable to be changed struct menuscreen* n_screen; //if the variable references another menu screen } menuitem; typedef struct //menuscreen { menuitem* choices[6];//the list of elements within a menu screen unsigned int cur_item :3;//the current item being edited in the menu } menuscreen; static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; volatile uint8_t old_AB; volatile int16_t r_counter=0; volatile int16_t r_enc=0; volatile int16_t midpoint, max_l, max_r, max_spd, spgm, spgd, sigm, sigd, min_spd, apgm, apgd, aigm, aigd, adgm, adgd, opgm, opgd, oigm, oigd, odgm, odgd; struct rg{ int rsw :1; int r1 :1; int r2 :2; int pressed :1; int edit_var :1; } reg; void menu_draw(menuscreen* screen, menuscreen** current)//first variable is the { LCD.clear(); *current=screen; uint8_t i; for(i=0;i<6;i++) { if(screen->choices[i]!=NULL) { LCD.set_cursor(screen->choices[i]->line, screen->choices[i]->position); LCD.print_s(screen->choices[i]->text); if(screen->choices[i]->variable!=NULL) { LCD.print_i(*(screen->choices[i]->variable)); }//end if }//end if } if(screen->cur_item==0) { for(i=0;i<6;i++) { if((screen->choices[i]->n_screen!=NULL)||(screen->choices[i]->variable!=NULL)) { screen->cur_item=i; break; }//end if }//end for }//end if LCD.set_cursor(screen->choices[screen->cur_item]->line, screen->choices[screen->cur_item]->position); } //end menu_draw void send_data() { uart_putc(midpoint>>8); uart_putc(midpoint&0xff); uart_putc(max_l>>8); uart_putc(max_l&0xff); uart_putc(max_r>>8); uart_putc(max_r&0xff); uart_putc(max_spd>>8); uart_putc(max_spd&0xff); uart_putc(spgm>>8); uart_putc(spgm&0xff); uart_putc(spgd>>8); uart_putc(spgd&0xff); uart_putc(sigm>>8); uart_putc(sigm&0xff); uart_putc(sigd>>8); uart_putc(sigd&0xff); uart_putc(min_spd>>8); uart_putc(min_spd&0xff); uart_putc(apgm>>8); uart_putc(apgm&0xff); uart_putc(apgd>>8); uart_putc(apgd&0xff); uart_putc(aigm>>8); uart_putc(aigm&0xff); uart_putc(aigd>>8); uart_putc(aigd&0xff); uart_putc(adgd>>8); uart_putc(adgd&0xff); uart_putc(opgm>>8); uart_putc(opgm&0xff); uart_putc(opgd>>8); uart_putc(opgd&0xff); uart_putc(oigm>>8); uart_putc(oigm&0xff); uart_putc(oigd>>8); uart_putc(oigd&0xff); uart_putc(odgm>>8); uart_putc(odgm&0xff); uart_putc(odgd>>8); uart_putc(odgd&0xff); }//end send data ISR(PCINT2_vect) { unsigned char port;//can be merged with the bottom one port=PIND&((1<<R1)|(1<<R2)|(1<<RSW)); if(reg.rsw!=((port&(1<<RSW))>>RSW)){ if(~(port&1<<RSW)&1<<RSW) //if the switch is low (all other pins masked) { r_enc=0; reg.pressed=1; }//end if reg.rsw=(port&(1<<RSW))>>RSW; } // if(rotary switch) if((reg.r1!=((port&(1<<R1))>>R1))||(reg.r2!=((port&(1<<R2))>>R2))) { old_AB <<= 2; //remember previous state old_AB |= ((port>>5) & 0x03); //add current state r_counter+=enc_states[(old_AB&0x0f)]; reg.r1=(port&(1<<R1))>>R1; reg.r2=(port&(1<<R2))>>R2; } // if (rotary encoder) reg.r1=(port&(1<<R1))>>R1; reg.r2=(port&(1<<R2))>>R2; if((r_counter%4)==0) { r_enc+=r_counter/4; r_counter=0; } } int main(void) { LCD.init(); LCD.clear(); LCD.cursor(); uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); switch_init(); menuscreen* cur_sc;//this variable keeps track of the current menu screen reg.r1=1; reg.r2=1; reg.rsw=1; /*The following code declares the different screens*/ menuscreen menu_main, menu_servo, menu_speed, menu_angle, menu_offset, menu_control; /*Angular PID Control Menu Items*********************************************/ /**************Menu Screen Angle Proportional**************/ menuscreen menu_angle_proportional; menuitem a_prop_title, a_prop_mult, a_prop_div;//editable parameters for the proprotional angle control menu_angle_proportional.choices[0]=&a_prop_title; menu_angle_proportional.choices[1]=&a_prop_mult; menu_angle_proportional.choices[2]=&a_prop_div; //Prop title a_prop_title.text="ANG PROPORTIONAL"; a_prop_title.line=0; a_prop_title.position=0; a_prop_title.variable=NULL; a_prop_title.n_screen=&menu_angle; //end prop title //prop multiplier a_prop_mult.text="APM:"; a_prop_mult.line=1; a_prop_mult.position=0; a_prop_mult.variable=&apgm; a_prop_mult.n_screen=NULL; //end prop multiplier //prop divisor a_prop_div.text="APD:"; a_prop_div.line=1; a_prop_div.position=8; a_prop_div.variable=&apgd; a_prop_div.n_screen=NULL; //end prop divisor /**************Menu Screen Angle Integral**************/ menuscreen menu_angle_integral; menuitem a_int_title, a_int_mult, a_int_div;//editable parameters for the derivative angle control menu_angle_integral.choices[0]=&a_int_title; menu_angle_integral.choices[1]=&a_int_mult; menu_angle_integral.choices[2]=&a_int_div; //integral title a_int_title.text="INTEGRAL"; a_int_title.line=0; a_int_title.position=0; a_int_title.variable=NULL; a_int_title.n_screen=&menu_angle; //end integral title //prop multiplier a_int_mult.text="AIM:"; a_int_mult.line=1; a_int_mult.position=0; a_int_mult.variable=&aigm; a_int_mult.n_screen=NULL; //end integral multiplier //integral divisor a_int_div.text="AID:"; a_int_div.line=1; a_int_div.position=8; a_int_div.variable=&aigd; a_int_div.n_screen=NULL; //end integral divisor /**************Menu Screen Angle Derivative**************/ menuscreen menu_angle_derivative; menuitem a_der_title, a_der_mult, a_der_div;//editable parameters for the integral angle control menu_angle_derivative.choices[0]=&a_der_title; menu_angle_derivative.choices[1]=&a_der_mult; menu_angle_derivative.choices[2]=&a_der_div; //Derivative title a_der_title.text="DERIVATIVE"; a_der_title.line=0; a_der_title.position=0; a_der_title.variable=NULL; a_der_title.n_screen=&menu_angle; //end Derivative title //Derivative multiplier a_der_mult.text="ADM:"; a_der_mult.line=1; a_der_mult.position=0; a_der_mult.variable=&adgm; a_der_mult.n_screen=NULL; //end Derivative multiplier //Derivative divisor a_der_div.text="ADD:"; a_der_div.line=1; a_der_div.position=8; a_der_div.variable=&adgd; a_der_div.n_screen=NULL; //end Derivative divisor /*************ANGLE Here we initialize the ANGLE menu items*************/ menuitem angle_title, prop, integral, derivative;//angle menu items menu_angle.choices[0]=&angle_title; menu_angle.choices[1]=∝ menu_angle.choices[2]=&integral; menu_angle.choices[3]=&derivative; //ANGLE angle_title.text="ANGLE:"; angle_title.line=0; angle_title.position=0; angle_title.variable=NULL; angle_title.n_screen=&menu_main; //end ANGLE //PROP prop.text="PROP"; prop.line=0; prop.position=9; prop.variable=NULL; prop.n_screen=&menu_angle_proportional; //end PROP //Integral integral.text="INTEGRAL"; integral.line=1; integral.position=0; integral.variable=NULL; integral.n_screen=&menu_angle_integral; //end Integral //dV/dt derivative.text="dv/dt"; derivative.line=1; derivative.position=9; derivative.variable=NULL; derivative.n_screen=&menu_angle_derivative; //end dV/dt /*Offset PID Control Menu Items*********************************************/ /**************Menu Screen Offset Proportional**************/ menuscreen menu_offset_proportional; menuitem o_prop_title, o_prop_mult, o_prop_div;//editable parameters for the proprotional offset control menu_offset_proportional.choices[0]=&o_prop_title; menu_offset_proportional.choices[1]=&o_prop_mult; menu_offset_proportional.choices[2]=&o_prop_div; //Prop title o_prop_title.text="OFS PROPORTIONAL"; o_prop_title.line=0; o_prop_title.position=0; o_prop_title.variable=NULL; o_prop_title.n_screen=&menu_offset; //end prop title //prop multiplier o_prop_mult.text="OPM:"; o_prop_mult.line=1; o_prop_mult.position=0; o_prop_mult.variable=&opgm; a_prop_mult.n_screen=NULL; //end prop multiplier //prop divisor o_prop_div.text="OPD:"; o_prop_div.line=1; o_prop_div.position=8; o_prop_div.variable=&opgd; o_prop_div.n_screen=NULL; //end prop divisor /**************Menu Screen Offset Integral**************/ menuscreen menu_offset_integral; menuitem o_int_title, o_int_mult, o_int_div;//editable parameters for the integral offset control menu_offset_integral.choices[0]=&o_int_title; menu_offset_integral.choices[1]=&o_int_mult; menu_offset_integral.choices[2]=&o_int_div; //integral title o_int_title.text="INTEGRAL"; o_int_title.line=0; o_int_title.position=0; o_int_title.variable=NULL; o_int_title.n_screen=&menu_offset; //end integral title //prop multiplier o_int_mult.text="OIM:"; o_int_mult.line=1; o_int_mult.position=0; o_int_mult.variable=&oigm; o_int_mult.n_screen=NULL; //end integral multiplier //integral divisor o_int_div.text="OID:"; o_int_div.line=1; o_int_div.position=8; o_int_div.variable=&oigd; o_int_div.n_screen=NULL; //end integral divisor /**************Menu Screen Offset Derivative**************/ menuscreen menu_offset_derivative; menuitem o_der_title, o_der_mult, o_der_div;//editable parameters for the derivative offset control menu_offset_derivative.choices[0]=&o_der_title; menu_offset_derivative.choices[1]=&o_der_mult; menu_offset_derivative.choices[2]=&o_der_div; //Derivative title o_der_title.text="DERIVATIVE"; o_der_title.line=0; o_der_title.position=0; o_der_title.variable=NULL; o_der_title.n_screen=&menu_offset; //end Derivative title //Derivative multiplier o_der_mult.text="ODM:"; o_der_mult.line=1; o_der_mult.position=0; o_der_mult.variable=&odgm; o_der_mult.n_screen=NULL; //end Derivative multiplier //Derivative divisor o_der_div.text="ODD:"; o_der_div.line=1; o_der_div.position=8; o_der_div.variable=&odgd; o_der_div.n_screen=NULL; //end Derivative divisor /*************OFFSET Here we initialize the OFFSET menu items*************/ menuitem offset_title, o_prop, o_integral, o_derivative;//offset menu items menu_offset.choices[0]=&offset_title; menu_offset.choices[1]=&o_prop; menu_offset.choices[2]=&o_integral; menu_offset.choices[3]=&o_derivative; //ANGLE offset_title.text="OFFSET:"; offset_title.line=0; offset_title.position=0; offset_title.variable=NULL; offset_title.n_screen=&menu_main; //end ANGLE //PROP o_prop.text="PROP"; o_prop.line=0; o_prop.position=8; o_prop.variable=NULL; o_prop.n_screen=&menu_offset_proportional; //end PROP //Integral o_integral.text="INTEGRAL"; o_integral.line=1; o_integral.position=0; o_integral.variable=NULL; o_integral.n_screen=&menu_offset_integral; //end Integral //dV/dt o_derivative.text="dv/dt"; o_derivative.line=1; o_derivative.position=9; o_derivative.variable=NULL; o_derivative.n_screen=&menu_offset_derivative; //end dV/dt /*************MAIN Here we initialize the MAIN menu items*************/ menuitem mainm, srv, spd, angle, offset;// main menu items menu_main.choices[0]=&mainm; menu_main.choices[1]=&srv; menu_main.choices[2]=&spd; menu_main.choices[3]=∠ menu_main.choices[4]=&offset; //MAINM mainm.text="MAIN"; mainm.line=0; mainm.position=0; mainm.variable=NULL; mainm.n_screen=NULL; //end MAINM //SRV srv.text="SERVO"; srv.line=0; srv.position=5; srv.variable=NULL; srv.n_screen=&menu_servo; //end SRV //SPD spd.text="SPEED"; spd.line=0; spd.position=11; spd.variable=NULL; spd.n_screen=&menu_speed; //end SPD //ANGLE angle.text="ANGLE"; angle.line=1; angle.position=0; angle.variable=NULL; angle.n_screen=&menu_angle; //end ANGLE //OFFSET offset.text="OFFSET"; offset.line=1; offset.position=6; offset.variable=NULL; offset.n_screen=&menu_offset; //end OFFSET /*************SERVO Here we initialize the SERVO menu items*************/ menuitem servo, midp, ml, mr;// servo menu items menu_servo.choices[0]=&servo; menu_servo.choices[1]=&midp; menu_servo.choices[2]=&ml; menu_servo.choices[3]=&mr; //SERVO servo.text="SERVO"; servo.line=0; servo.position=0; servo.variable=NULL; servo.n_screen=&menu_main; //end SERVO //MIDPosition midp.text="OFST:"; midp.line=0; midp.position=7; midp.variable=&midpoint; midp.n_screen=NULL; //end MIDPosition //MaxLeft ml.text="ML:"; ml.line=1; ml.position=0; ml.variable=&max_l; ml.n_screen=NULL; //end MaxLeft //MaxRight mr.text="MR:"; mr.line=1; mr.position=8; mr.variable=&max_r; mr.n_screen=NULL; //end MaxRight /*************SPEED Here we initialize the SPEED menu items*************/ menuitem speed, highsp, lowsp, control;//speed menu items menu_speed.choices[0]=&speed; menu_speed.choices[1]=&control; menu_speed.choices[2]=&highsp; menu_speed.choices[3]=&lowsp; //SPEED speed.text="SPEED"; speed.line=0; speed.position=0; speed.variable=NULL; speed.n_screen=&menu_main; //end SPEED //High SPeed limit highsp.text="HSP:"; highsp.line=1; highsp.position=0; highsp.variable=&max_spd; highsp.n_screen=NULL; //end HSP //Low SPeed limit lowsp.text="LSP:"; lowsp.line=1; lowsp.position=8; lowsp.variable=&min_spd; lowsp.n_screen=NULL; //end LSP //ConTRoL control.text="CTRL"; control.line=0; control.position=7; control.variable=NULL; control.n_screen=&menu_control; //end CTRL /*************CONTROL Here we initialize the CONTROL menu items*************/ menuitem pgm, pgd, igm, igd, xit;//control menu items menu_control.choices[0]=&xit; menu_control.choices[1]=&pgm; menu_control.choices[2]=&pgd; menu_control.choices[3]=&igm; menu_control.choices[4]=&igd; //exit xit.text="XT"; xit.line=0; xit.position=0; xit.variable=NULL; xit.n_screen=&menu_main; //end exit //proportional gain pgm.text="PGM:"; pgm.line=0; pgm.position=3; pgm.variable=&spgm; pgm.n_screen=NULL; //end SPEED //High SPeed limit pgd.text="PGD:"; pgd.line=0; pgd.position=10; pgd.variable=&spgd; pgd.n_screen=NULL; //end HSP //Low SPeed limit igm.text="IGM:"; igm.line=1; igm.position=0; igm.variable=&sigm; igm.n_screen=NULL; //end LSP //ConTRoL igd.text="IGD:"; igd.line=1; igd.position=8; igd.variable=&sigd; igd.n_screen=NULL; //end CTRL DDRB|=1<<PINB0; menu_draw(&menu_main, &cur_sc); sei(); int16_t oldcounter=0; char c; while(1) { c = uart_getc(); if ( c & UART_NO_DATA ) {;}//if else// error handling { /* * new data available from UART * check for Frame or Overrun error */ if ( c & UART_FRAME_ERROR ) { /* Framing Error detected, i.e no stop bit detected */ LCD.clear(); LCD.set_cursor(0,0); LCD.print_s("UART Frame Error"); } if ( c & UART_OVERRUN_ERROR ) { /* * Overrun, a character already present in the UART UDR register was * not read by the interrupt handler before the next character arrived, * one or more received characters have been dropped */ LCD.clear(); LCD.set_cursor(0,0); LCD.print_s("UART Overrun"); } if ( c & UART_BUFFER_OVERFLOW ) { /* * We are not reading the receive buffer fast enough, * one or more received character have been dropped */ LCD.clear(); LCD.set_cursor(0,0); LCD.print_s("Buffer overflow"); } char temp[2]; temp[0]=c; temp[1]='\0'; } //else if(r_enc) { if(reg.edit_var) { LCD.set_cursor(cur_sc->choices[cur_sc->cur_item]->line, cur_sc->choices[cur_sc->cur_item]->position); LCD.print_s(cur_sc->choices[cur_sc->cur_item]->text); *(cur_sc->choices[cur_sc->cur_item]->variable)+=r_enc; LCD.print_i(*(cur_sc->choices[cur_sc->cur_item]->variable)); LCD.set_cursor(cur_sc->choices[cur_sc->cur_item]->line, cur_sc->choices[cur_sc->cur_item]->position); LCD.print_s(cur_sc->choices[cur_sc->cur_item]->text); r_enc=0; } else { cur_sc->cur_item+=r_enc; while(((cur_sc->choices[cur_sc->cur_item]->variable==NULL)&&(cur_sc->choices[cur_sc->cur_item]->n_screen==NULL))||cur_sc->choices[cur_sc->cur_item]==NULL) /* while the current variable and the current next screen are equal to NULL or if the current item is equal to NULL*/ { cur_sc->cur_item+=r_enc; if(cur_sc->cur_item>5) { if(r_enc>0){cur_sc->cur_item=0;} else {cur_sc->cur_item=5;} } }//end while r_enc=0; LCD.set_cursor(cur_sc->choices[cur_sc->cur_item]->line, cur_sc->choices[cur_sc->cur_item]->position); } }//end if if(reg.pressed) { if(cur_sc->choices[cur_sc->cur_item]->variable!=NULL) //if there is a variable to be changed { reg.edit_var^=1; if(reg.edit_var==0) { LCD.set_cursor(cur_sc->choices[cur_sc->cur_item]->line, cur_sc->choices[cur_sc->cur_item]->position); send_data(); } } else if((cur_sc->choices[cur_sc->cur_item]->n_screen)!=NULL) //if the click leads to another screen { menu_draw(cur_sc->choices[cur_sc->cur_item]->n_screen, &cur_sc); } reg.pressed=0; }//end if }//end while (1) }//end main inline void switch_init(void) { PCMSK2|=(1<<R1|1<<R2|1<<RSW); //allow interrupts for switches PCICR|=1<<PCIE2; DDRD&=~(1<<R1|1<<R2|1<<RSW); //set pins to input PORTD|=(1<<R1|1<<R2|1<<RSW); }D80; 50/1.8D; Tamron 70-300; 18-55 VR;
-
28th April 2013 22:28 #2
, , (GUI e ), - . .
(AVR + GUI + Google) . , , , . , .




Reply With Quote
Lenovo ThinkPad 15 IdeaPad 15
5th May 2023, 22:16 in