Advertisement
Guest User

Untitled

a guest
May 22nd, 2020
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.48 KB | None | 0 0
  1. #include <msp430.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4.  
  5. // Variables para la LCD:
  6.  
  7. typedef unsigned char byte;
  8. #define Enable_LCD 0x04
  9. #define iluminacion_LCD 0x08
  10. #define comando_LCD 0x00
  11. #define dato_LCD 0x01
  12. #define LCD_PCF8574_ADDRESS 0x27 // Slave address poniendo A0,A1,A2 = 1
  13.  
  14. // Variables para el ADC:
  15.  
  16. volatile uint8_t buffer_lleno = 0;
  17. uint16_t valor_promedio_A0 = 0; // Variable that stores average value of A0
  18. uint16_t valor_promedio_A1 = 0; // Variable that stores average value of A1
  19.  
  20. uint8_t *PTxData; // Pointer to TX
  21. uint8_t TXByteCtr; // Counter of bytes send
  22.  
  23. uint16_t volatile contador_milisegundos;
  24.  
  25. void Inicializacion_Relojes(void)
  26. {
  27. __bis_SR_register(SCG0); // Disable the FLL control loop
  28. UCSCTL0 = 0x0000;
  29. UCSCTL1 = DCORSEL_5;
  30. UCSCTL2 = FLLD_0 | 487;
  31. // (N + 1) * (FLLRef/n) = Fdcomsp430
  32. // (487 + 1) * (32768/1) = 16MHz
  33. UCSCTL3 = 0; // FLL SELREF = XT1CLK y divisor de FLL = 1 (FLLREFDIV = FLLREFCLK/1)
  34. UCSCTL4 |= SELA_0 | SELS_4 | SELM_4; // Tomamos ACLK = XT1CLK (Cuarzo externo de 2^15 bits); SMCLK = MCLK = DCOCLKDIV (DCO interno de 16 MHz)
  35. // UCSCTL5 |= DIVA_0 | DIVS_0;
  36. __bic_SR_register(SCG0); // Enable the FLL control loop
  37. }
  38.  
  39. void USCIB1_init()
  40. {
  41. P4SEL |= BIT2 | BIT1; // P4.1 --> UCB1SDA
  42. // P4.2 --> UCB1SCL
  43. UCB1CTL1 |= UCSWRST;
  44. UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // UCMST: Master; UCMODE_3: Modulo USCI como I2C; UCSYNC: Modo Sincrono
  45. UCB1CTL1 |= (UCSSEL_2 | UCSWRST); // UCSSEL_2: SMCLK; UCSWRST: Usci sigue en estado Reset
  46. UCB1BR0 = 160; // fSCL = SMCLK(16MHz)/160 = 100kHz
  47. UCB1BR1 = 0;
  48. UCB1CTL1 &= ~UCSWRST;
  49. UCB1IE |= UCTXIE;
  50. }
  51.  
  52. void delay_ms(uint16_t tiempo_milisegundos)
  53. {
  54. contador_milisegundos = 0;
  55. TA1CTL |= MC_1; UP MODE
  56. TA1CCTL0 |= CCIE;
  57. while(contador_milisegundos < tiempo_milisegundos);
  58. TA1CTL |= MC_0; // STOP MODE
  59. }
  60.  
  61. void init_TimerA1_ms(void)
  62. { // Timer for counting every ms for delay_ms
  63. TA1CCR0 = 16000-1;
  64. TA1CTL |= TASSEL_2 | MC_0; // Reloj SMCLK, Frecuencia: 16 MHz. Modo Stop.
  65. }
  66.  
  67. // Funcion para configurar el ADC:
  68.  
  69. void ConfiguracionADC(void){
  70. P6SEL |= BIT0 | BIT1; // enable P6.0 y P6.1 as A/D channels
  71. ADC12CTL0 |= ADC12SHT0_5 | ADC12MSC | ADC12ON; // ADC12ON: enable el ADC; ADC12SHT0_5: 64 sample cycles del S & H
  72. ADC12CTL1 |= ADC12SSEL_3 | ADC12DIV_7 | ADC12CONSEQ_3 | ADC12SHP; // ADC12SSEL_3: SMCLK; ADC12DIV_7: Preescalador de 8; ADC12CONSEQ_3: Repeat-Sequence-of-Channels Mode
  73. ADC12MCTL0 |= ADC12SREF_0 | ADC12INCH_0; // ADC12SREF_0: VR+ = AVcc+ and VR- = AVss ; ADC12INCH_0: Canal A0
  74. ADC12MCTL1 |= ADC12SREF_0 | ADC12INCH_1 | ADC12EOS; // ADC12INCH_1: Canal A1; ADC12EOS: end of sequence
  75. ADC12CTL0 |= ADC12ENC; // ADC12ENC: enable conversion
  76. ADC12IE |= BIT1; // enable ADC12IFG.1
  77. }
  78.  
  79. void I2C_send(byte addr, byte *buffer, byte numero_datos)
  80. {
  81. UCB1I2CSA = addr;
  82. PTxData = buffer;
  83. TXByteCtr = numero_datos;
  84. UCB1CTL1 |= (UCTR | UCTXSTT);
  85. __bis_SR_register(LPM0_bits + GIE);
  86. __no_operation();
  87. while(UCB1CTL1 & UCTXSTP);
  88. }
  89.  
  90. void lcd_send_nibble_cmd(byte dato)
  91. {
  92. byte buffer[2];
  93. byte dato_I2C_H;
  94. dato_I2C_H = dato & 0xF0;
  95. buffer[0] = dato_I2C_H | iluminacion_LCD | Enable_LCD | comando_LCD;
  96. buffer[1] = dato_I2C_H | iluminacion_LCD | comando_LCD;
  97. I2C_send(LCD_PCF8574_ADDRESS, buffer, 2);
  98. }
  99.  
  100. void lcd_send_byte_data(byte dato)
  101. {
  102. byte buffer[4];
  103. byte dato_I2C_H, dato_I2C_L;
  104. dato_I2C_H = dato & 0xF0;
  105. dato_I2C_L = (dato << 4) & 0xF0;
  106. buffer[0] = dato_I2C_H | iluminacion_LCD | Enable_LCD | dato_LCD;
  107. buffer[1] = dato_I2C_H | iluminacion_LCD | dato_LCD;
  108. buffer[2] = dato_I2C_L | iluminacion_LCD | Enable_LCD | dato_LCD;
  109. buffer[3] = dato_I2C_L | iluminacion_LCD | dato_LCD;
  110. I2C_send(LCD_PCF8574_ADDRESS, buffer, 4);
  111. }
  112.  
  113. void lcd_send_byte_cmd(byte dato)
  114. {
  115. byte buffer[4];
  116. byte dato_I2C_H, dato_I2C_L;
  117. dato_I2C_H = dato & 0xF0;
  118. dato_I2C_L = (dato << 4) & 0xF0;
  119. buffer[0] = dato_I2C_H | iluminacion_LCD | Enable_LCD | comando_LCD;
  120. buffer[1] = dato_I2C_H | iluminacion_LCD | comando_LCD;
  121. buffer[2] = dato_I2C_L | iluminacion_LCD | Enable_LCD | comando_LCD;
  122. buffer[3] = dato_I2C_L | iluminacion_LCD | comando_LCD;
  123. I2C_send(LCD_PCF8574_ADDRESS, buffer, 4);
  124. }
  125.  
  126. void init_LCD_PCF8574(void)
  127. {
  128. delay_ms(20);
  129. lcd_send_nibble_cmd(0x30);
  130. delay_ms(5);
  131. lcd_send_nibble_cmd(0x30);
  132. delay_ms(1);
  133. lcd_send_nibble_cmd(0x30);
  134. delay_ms(5);
  135. lcd_send_nibble_cmd(0x20); // data bus of 4 bits
  136.  
  137. delay_ms(1);
  138. lcd_send_byte_cmd(0x28);
  139. delay_ms(1);
  140. lcd_send_byte_cmd(0x08); // Display off, Cursor off, Blink off
  141. delay_ms(1);
  142. lcd_send_byte_cmd(0x01); // Clear Screen, Cursor Home
  143. delay_ms(2);
  144. lcd_send_byte_cmd(0x06); // Entry mode set; I/D=1: Incremento;
  145. delay_ms(10);
  146. lcd_send_byte_cmd(0x0D); // Display ON, Cursor ON, Cursor Blink
  147. delay_ms(10);
  148. }
  149.  
  150. void lcd_setCursor(byte fila, byte columna)
  151. {
  152. byte address;
  153.  
  154. if (fila == 0){ // first row
  155. address = 0;
  156. }
  157. else address = 0x40; // Second row
  158.  
  159. address |= columna; // Para tener 0x00 + Columna (Fila1)
  160. // Para tener 0x40 + Columna (Fila2)
  161.  
  162. lcd_send_byte_data(0x80 | address); // Set DDRAM Address
  163. delay_ms(2);
  164. }
  165.  
  166. void lcd_print(char *string, uint8_t fila, uint8_t columna)
  167. {
  168. uint8_t tamaño;
  169. lcd_setCursor(fila,columna);
  170.  
  171. while(*string != '\0')
  172. {
  173. lcd_send_byte_data(*string++); // write the character on the LCD
  174. tamaño++;
  175. if(tamaño > (16-columna))
  176. {
  177. lcd_send_byte_cmd(0x18); // Display shift to left
  178. delay_ms(300); // delay to see how characters are shifted
  179. }
  180. }
  181. delay_ms(2);
  182. }
  183.  
  184. void borrar_pantalla(void)
  185. {
  186. lcd_send_byte_cmd(0x01); // clear display
  187. delay_ms(2);
  188. lcd_send_byte_cmd(0x02); // Return Home
  189. delay_ms(2);
  190. }
  191.  
  192. void main(void)
  193. {
  194. char datos_A0[4], datos_A1[4];
  195. WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
  196. Inicializacion_Relojes();
  197. USCIB1_init();
  198. init_TimerA1_ms();
  199. __enable_interrupt();
  200. init_LCD_PCF8574();
  201. borrar_pantalla(); // delete anything that could appear in the display, for clearing it
  202. lcd_print("Hello Worlddddddddddddddd!",0,0); // Message to show that LCD display seems to work fine
  203. delay_ms(1000);
  204. borrar_pantalla();
  205. ConfiguracionADC();
  206. delay_ms(300); // wait for stabilize voltage reference
  207. ADC12CTL0 |= ADC12SC; // ADC12SC: begins the conversion
  208. __bis_SR_register(LPM0_bits + GIE);
  209. while(1){
  210. if (buffer_lleno == 1){
  211. sprintf(datos_A0,"valor ADC_A0=%d",valor_promedio_A0);
  212. sprintf(datos_A1,"valor ADC_A1=%d",valor_promedio_A1);
  213. lcd_print(datos_A0,0,4); // In row 0 of the LCD i put the A1 average value
  214. lcd_print(datos_A1,1,4); // In row 1 of the LCD i put the A1 average value
  215. valor_promedio_A0 = 0; // Reset value of A0
  216. valor_promedio_A1 = 0; // Reset value of A1
  217. buffer_lleno = 0;
  218. ADC12CTL0 |= ADC12ENC; // enable ADC
  219. }
  220. }
  221. }
  222.  
  223. #pragma vector=TIMER1_A0_VECTOR
  224. __interrupt void timer1_A0_ISR(void){
  225. contador_milisegundos++;
  226. TA1CCTL0 &= ~CCIFG;
  227. }
  228.  
  229. #pragma vector = USCI_B1_VECTOR
  230. __interrupt void usci_b1_isr(void)
  231. {
  232. switch(__even_in_range(UCB1IV,12))
  233. {
  234. case 0: break; // Vector 0: No interrupts
  235. case 2: break; // Vector 2: ALIFG
  236. case 4: break; // Vector 4: NACKIFG
  237. case 6: break; // Vector 6: STTIFG
  238. case 8: break; // Vector 8: STPIFG
  239. case 10: break; // Vector 10: RXIFG
  240. case 12: // Vector 12: TXIFG
  241. if (TXByteCtr) // Check TX byte counter
  242. {
  243. UCB1TXBUF = *PTxData++; // Load TX buffer
  244. TXByteCtr--; // Decrement TX byte counter
  245. }
  246. else
  247. {
  248. UCB1CTL1 |= UCTXSTP; // I2C stop condition
  249. UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
  250. __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
  251. }
  252. default: break;
  253. }
  254. }
  255.  
  256. #pragma vector=ADC12_VECTOR
  257. __interrupt void ADC12ISR (void)
  258. {
  259. static unsigned int index = 0;
  260. switch(__even_in_range(ADC12IV,34))
  261. {
  262. case 0: break; // Vector 0: No interrupt
  263. case 2: break; // Vector 2: ADC overflow
  264. case 4: break; // Vector 4: ADC timing overflow
  265. case 6: break;
  266. case 8: // Vector 8: ADC12IFG1
  267. valor_promedio_A0 += ADC12MEM0;
  268. valor_promedio_A1 += ADC12MEM1;
  269. index++;
  270. if (index == 8){
  271. buffer_lleno = 1;
  272. valor_promedio_A0 >>= 3; // To divide by 8 to take the average value cause i had measured 8 samples.
  273. valor_promedio_A1 >>= 3;
  274. index = 0;
  275. ADC12CTL0 &= ~ADC12ENC; // Deshabilitamos el ADC
  276. }
  277. break;
  278. case 10: break; // Vector 10: ADC12IFG2
  279. case 12: break; // Vector 12: ADC12IFG3
  280. case 14: break; // Vector 14: ADC12IFG4
  281. case 16: break; // Vector 16: ADC12IFG5
  282. case 18: break; // Vector 18: ADC12IFG6
  283. case 20: break; // Vector 20: ADC12IFG7
  284. case 22: break; // Vector 22: ADC12IFG8
  285. case 24: break; // Vector 24: ADC12IFG9
  286. case 26: break; // Vector 26: ADC12IFG10
  287. case 28: break; // Vector 28: ADC12IFG11
  288. case 30: break; // Vector 30: ADC12IFG12
  289. case 32: break; // Vector 32: ADC12IFG13
  290. case 34: break; // Vector 34: ADC12IFG14
  291. default: break;
  292. }
  293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement