Advertisement
Guest User

Untitled

a guest
Jun 18th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.95 KB | None | 0 0
  1. /**
  2. * @file main.c
  3. * @brief Programm zur Demonstration der Verwendung des Beschleunigungssensors MMA7660FC im
  4. * Zusammenspiel mit der I²C Master Schnittstelle des MSP430G2553 und dem MSP430 launchpad.
  5. * Das Programm liest die X-, Y- und Z-Komponente des Beschleunigungssensors ein und
  6. * gibt die Daten im Sekundentakt auf die RS232 Schnittstelle des launchpads aus, so dass
  7. * die Daten über das virtuelle COM-Port des launchpads auf einem PC eingelesen werden können.
  8. * @author stesStd
  9. * @date 07.06.2015
  10. *
  11. * @todo
  12. * - Fehlerbehandlungen einbauen:
  13. * # I2C-Kommunikation
  14. * # Zeitüberschreitungen bei den states der main-loop: bisher Einschalten der roten LED
  15. * - MMA7660 LPM ausnutzen: der Sensor läuft momentan ohne Nutzung seiner Power Optimierung
  16. * - Erweiterung des Ansatzes zur zeitgleichen Nutzung mehrerer I²C-slaves unter Verwendung
  17. * von vorgegebenen Slave Adressen
  18. * - Vervollständigung der Doxygen Dokumentation
  19. *
  20. */
  21.  
  22.  
  23. #include <stdint.h>
  24. #include <stdbool.h>
  25. /*
  26. * ======== Standard MSP430 includes ========
  27. */
  28. #include <msp430.h>
  29. /*
  30. * ======== Grace related includes ========
  31. */
  32. #include <ti/mcu/msp430/Grace.h>
  33. /*
  34. * ======== Project related includes ========
  35. */
  36. #include "i2cSM.h"
  37. #include "rs232_SM.h"
  38.  
  39. /*
  40. * ======== main ========
  41. */
  42.  
  43.  
  44. //timekeeping registers
  45. #define DS3231_TIME_CAL_ADDR 0x00
  46. #define DS3231_ALARM1_ADDR 0x07
  47. #define DS3231_ALARM2_ADDR 0x0B
  48. #define DS3231_CONTROL_ADDR 0x0E
  49. #define DS3231_STATUS_ADDR 0x0F
  50. #define DS3231_AGING_OFFSET_ADDR 0x10
  51. #define DS3231_TEMPERATURE_ADDR 0x11
  52.  
  53.  
  54. /** Datenstruktur zur Übergabe einer Registeradresse und eines Datenbytes */
  55. typedef union {
  56. struct ts {
  57. uint8_t sec; /* seconds */
  58. uint8_t min; /* minutes */
  59. uint8_t hour; /* hours */
  60. uint8_t mday; /* day of the month */
  61. uint8_t mon; /* month */
  62. int16_t year; /* year */
  63. uint8_t wday; /* day of the week */
  64. uint8_t yday; /* day in the year */
  65. uint8_t isdst; /* daylight saving time */
  66. uint8_t year_s; /* year in short notation*/
  67. #ifdef CONFIG_UNIXTIME
  68. uint32_t unixtime; /* seconds since 01.01.1970 00:00:00 UTC*/
  69. #endif
  70. };
  71. uint8_t val[2]; /**<Datenarray für I2C Datenübertragung */
  72. } TUnion_Register;
  73.  
  74.  
  75.  
  76. int itoa(int n, char s[]);
  77.  
  78.  
  79.  
  80. int main(void)
  81. {
  82. /** Einzelstati, die im Hauptprogramm durchlaufen werden. */
  83. static enum {
  84. MMA_initDeactivate, /**< Sensor in standby schalten, damit Steuerregister geschrieben werden können */
  85. MMA_initCtrlReg, /**< Sensor Steuerregister initialisieren */
  86. MMA_initActivate, /**< Sensor nach Schreiben der Steuerregister wieder aktivieren */
  87. MMA_setReadStartReg, /**< Registeradresse für Leseoperation übertragen */
  88. MMA_readDataReg, /**< Lesen der Ergebnisregister starten */
  89. MMA_w4Res, /**< auf Abschluss der Leseoperation warten */
  90. RS232_writeRes, /**< auf Abschluss der RS232 Schreiboperation warten */
  91. N_cnt /**< letzter enum gibt an, wieviele states definiert sind */
  92. } eMMA7660state = MMA_initDeactivate;
  93.  
  94. /** 7-Bit Adresse des MMA7660FC-Sensors: Dieser Wert muss in das Steuerregister des MSP430
  95. * eingetragen werden. DEr MSP430 ergänzt das 8. Bit (LSB) mit einer 0 oder einer 1, je
  96. * nachdem, ob auf den Sensor geschrieben oder vom Sensor gelesen werden soll */
  97. const uint8_t mmA7660_sensorAddr = 0x68; //ersetzen durch RTC als var name
  98.  
  99.  
  100. /** Definition der an die Steuerregister zu übertragenden Werte (siehe Application note) */
  101. const uint8_t mma7660InitData[] = {
  102. 0x05, //00: Adresse des ersten Control Registers
  103. 0x00, //02: Einstellung für Sleep Count
  104. 0x04, //03: Einstellung für Interrupt Setup
  105. 0x00, //04: Einstellung für Mode: der bleibt während der Initialisierung auf inaktiv
  106. 0x00, //05: Einstellung für SR-Register
  107. 0x74, //06: Schwelle für Tap Detection: gemäß Appl.-note: 0x6C
  108. 0x0B //07: Tap Debounce Count: gemäß Appl.-note: 0x08
  109. };
  110.  
  111. /** Datenpuffer zur Aufnahme einer Registeradresse und eines Datenwertes */
  112. TUnion_Register singleByteDataBuf;
  113.  
  114. /** Datenpuffer zum Einlesen der Ergebnisregister */
  115. uint8_t readBuf[8];
  116.  
  117. /** substate vom RS232_writeRes - State */
  118. static uint16_t m_uiRS232_writeRes_SubState;
  119.  
  120. /** Counter, der bei jedem durch den mit Timer A0 realisierten System-Tick inkrementiert wird */
  121. static volatile uint16_t m_uiTimerCnt = 0;
  122.  
  123.  
  124. Grace_init(); // Activate Grace-generated configuration
  125.  
  126. while (1) {
  127.  
  128. m_uiTimerCnt++; //System-Tick Zähler inkrementieren
  129.  
  130. P1OUT |= BIT5; //P1.5 aktivieren: diese bleibt im on-state, solange die
  131. //main-loop im active state ist und wird deaktiviert, sobald
  132. //der sleep mode aktiviert wird: Auf diese Weise kann mit einem
  133. //Oszi das On/Off -Verhältnis der CPU bestimmt werden.
  134.  
  135. ProcessI2C(); //abarbeiten der seit dem letzten Timer-Tick aufgelaufenen I2C-Events
  136.  
  137. switch (eMMA7660state) {
  138. case MMA_initDeactivate:
  139. //Warten bis Programm gestartet wird, damit der Sensor zur Konfiguration
  140. //deaktiviert werden kann:
  141. singleByteDataBuf.s.reg = DS3231_TIME_CAL_ADDR;
  142. singleByteDataBuf.s.data = 0x00;
  143. if (!i2cSendData(mmA7660_sensorAddr, 2, NO_RESTART, (const uint8_t*)&singleByteDataBuf)) {
  144. //Fehlermeldung: rote LED anschalten
  145. //Zeitintervall des Systemtimers hat für Datenübertragung nicht gereicht!
  146. P1OUT |= BIT0;
  147. }
  148. else {
  149. eMMA7660state++;
  150. }
  151. break;
  152.  
  153. case MMA_initCtrlReg:
  154. //Warten, bis der Sensor deaktiviert wurde, damit anschließend die Übertragung
  155. //der Konfigurationsdaten gestartet werden kann:
  156. if (!i2cSendData(mmA7660_sensorAddr, sizeof(mma7660InitData), NO_RESTART, mma7660InitData)) {
  157. //Fehlermeldung: rote LED anschalten
  158. //Zeitintervall des Systemtimers hat für Datenübertragung nicht gereicht!
  159. P1OUT |= BIT0;
  160.  
  161. }
  162. else {
  163. eMMA7660state++;
  164. }
  165. break;
  166.  
  167. case MMA_initActivate:
  168. //Warten, bis die Konfigurationsdaten übertragen sind, damit anschließend der
  169. //Sensor wieder aktiviert werden kann:
  170. singleByteDataBuf.s.reg = MODE_REG;
  171. singleByteDataBuf.s.data = 0x01;
  172. if (!i2cSendData(mmA7660_sensorAddr, 2, NO_RESTART, (const uint8_t*)&singleByteDataBuf)) {
  173. //Fehlermeldung: rote LED anschalten
  174. //Zeitintervall des Systemtimers hat für Datenübertragung nicht gereicht!
  175. P1OUT |= BIT0;
  176. }
  177. else {
  178. eMMA7660state++;
  179. }
  180. break;
  181.  
  182. case MMA_setReadStartReg:
  183. //Warten, bis der Sensor aktiviert ist, damit anschließend die Adresse des
  184. //ersten zu lesenden Ergebnisregister übertragen werden kann:
  185. //Wichtig: der Sensor löscht die übertragene Leseadresse, wenn die Schreiboperation
  186. //mit einem STOP-Signal abgeschlossen wird. Aus diesem Grund darf die Übertragung
  187. //der Startadresse nicht mit einem STOP-Signal abgeschlossen werden, so dass die
  188. //nächste Datensequenz (Aufforderung zum Lesezugriff) mit einem RESTART begonnen
  189. //werden kann (siehe Datenblatt des MMA7660)
  190. singleByteDataBuf.s.reg = XOUT_REG;
  191. if (!i2cSendData(mmA7660_sensorAddr, 1, RESTART, (const uint8_t*)&singleByteDataBuf)) {
  192. //Fehlermeldung: rote LED anschalten
  193. //Zeitintervall des Systemtimers hat für Datenübertragung nicht gereicht!
  194. P1OUT |= BIT0;
  195. }
  196. else {
  197. eMMA7660state++;
  198. }
  199. break;
  200.  
  201. case MMA_readDataReg:
  202. //Warten, bis die Startadresse übertragen ist, damit anschließend mit dem Einlesen
  203. //der Ergebnisdaten begonnen werden kann:
  204. if (!i2cReceiveData(mmA7660_sensorAddr, 8, readBuf)) {
  205. //Fehlermeldung: rote LED anschalten
  206. //Zeitintervall des Systemtimers hat für Datenübertragung nicht gereicht!
  207. P1OUT |= BIT0;
  208. }
  209. else {
  210. eMMA7660state++;
  211. }
  212. break;
  213.  
  214. case MMA_w4Res:
  215. //Warten, bis die Startadresse übertragen ist, damit anschließend auf den
  216. //Abschluss des Einlesens der Ergebnisdaten gewartet werden kann:
  217. if (i2cGetRdyState() == true) {
  218. m_uiRS232_writeRes_SubState = 0;
  219. eMMA7660state++;
  220. }
  221. else {
  222. //Fehlermeldung: rote LED anschalten
  223. //Zeitintervall des Systemtimers hat für Datenübertragung nicht gereicht!
  224. P1OUT |= BIT0;
  225. }
  226. break;
  227.  
  228.  
  229. }
  230.  
  231. //P1.5 ausschalten, bevor in den Sleep-Modus gewechselt wird
  232. P1OUT &= ~BIT5;
  233. LPM1;
  234. }
  235.  
  236. return (0);
  237. }
  238.  
  239.  
  240.  
  241.  
  242. int itoa(int n, char s[])
  243. {
  244. int ii, signedVal;
  245.  
  246. if ((signedVal = n) < 0) {
  247. n = -n; /* Betrag bilden */
  248. }
  249.  
  250. ii = 0;
  251. do {
  252. s[ii++] = n % 10 + '0'; /* 10er Dezimale in ASCII wandeln */
  253. } while ((n /= 10) > 0);
  254.  
  255. if (signedVal < 0) {
  256. s[ii++] = '-'; /* Vorzeichen zuweisen */
  257. }
  258. else if (signedVal > 0) {
  259. s[ii++] = '+';
  260. }
  261. else {
  262. //nix
  263. }
  264. //s[ii] = '\0';
  265. return ii;
  266. }
  267.  
  268.  
  269. //********************************************************************************************************/
  270. /*! @fn function signature
  271. * @brief short description of function
  272. * @author stesStd
  273. * @version x
  274. *
  275. * @date __Version x (ab 20yy-mm-dd)__
  276. * - geändert: 20yy-mm-dd (stesStd)
  277. * - Kommentierung der Änderungen
  278. * - Test und Freigabe: 20yy-mm-dd (stesStd)
  279. * - Testresultate
  280. *
  281. * @date __Version 1 (ab 20yy-mm-dd)__
  282. * - erstellt: 20yy-mm-dd (stesStd)
  283. * - Erstausgabe der Funktion
  284. * - Test und Freigabe: 20yy-mm-dd (stesStd)
  285. * - Testergebnisse
  286.  
  287. * @param [in] Name (Typ): Beschreibung oder leer
  288. * @param [out] Name (Typ): Beschreibung oder leer
  289. * @param [in,out] Name (Typ): Beschreibung oder leer
  290. * @return Typ: Beschreibung oder void
  291. *
  292. * Zweck:
  293. * ------
  294. * -# Zweck x(n)
  295. * - Zweck x(n).y
  296. * -# Zweck x(n+1)
  297. * - Zweck x(n+1).y
  298. *
  299. * Umsetzung:
  300. * ----------
  301. * - Beschreibung (n)
  302. * - Beschreibung (n+1)
  303. *
  304. * @sa Referenzen auf andere Funktionen oder löschen
  305. *
  306. * @init Schritte zur Vorbereitung des Funktionsaufrufs oder nicht erforderlich
  307. *
  308. * @test Prüfen, ob nach dem Aufruf:
  309. * - Test 1
  310. - Test ...
  311. * - Test n
  312. *
  313. * @code
  314. * kein Beispielcode
  315. * @endcode
  316. *
  317. * @warning - Warnhinweis 1 oder nicht belegt
  318. *
  319. * @riskman - RM-Hinweis 1 oder keine Hinweise zum Risikomanagement
  320. *
  321. * @todo
  322. *
  323. ************************************************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement