#include "LiquidCrystal.h"#include <stdio.h>#include <string.h>#include <inttypes.h>#include "Arduino.h"// When the display powers up, it is configured as follows://// 1. Display clear// 2. Function set: // DL = 1; 8-bit interface data // N = 0; 1-line display // F = 0; 5x8 dot character font // 3. Display on/off control: // D = 0; Display off // C = 0; Cursor off // B = 0; Blinking off // 4. Entry mode set: // I/D = 1; Increment by 1 // S = 0; No shift //// Note, however, that resetting the Arduino doesn't reset the LCD, so we// can't assume that its in that state when a sketch starts (and the// LiquidCrystal constructor is called).LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7){ init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);}LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7){ init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);}LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3){ init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);}LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3){ init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);}void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7){ _rs_pin = rs; _rw_pin = rw; _enable_pin = enable; _data_pins[0] = d0; _data_pins[1] = d1; _data_pins[2] = d2; _data_pins[3] = d3; _data_pins[4] = d4; _data_pins[5] = d5; _data_pins[6] = d6; _data_pins[7] = d7; if (fourbitmode) _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; else _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;#ifndef __ARDUINO_X86__ begin(16, 1);#endif }void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { if (lines > 1) { _displayfunction |= LCD_2LINE; } _numlines = lines; _currline = 0; // for some 1 line displays you can select a 10 pixel high font if ((dotsize != 0) && (lines == 1)) { _displayfunction |= LCD_5x10DOTS; } // Deferred initialized from init() pinMode(_rs_pin, OUTPUT); // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# if (_rw_pin != 255) { pinMode(_rw_pin, OUTPUT); } pinMode(_enable_pin, OUTPUT); // Do these once, instead of every time a character is drawn for speed reasons. for (int i=0; i<((_displayfunction & LCD_8BITMODE) ? 8 : 4); ++i) pinMode(_data_pins[i], OUTPUT); // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! // according to datasheet, we need at least 40ms after power rises above 2.7V // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 delayMicroseconds(50000); // Now we pull both RS and R/W low to begin commands digitalWrite(_rs_pin, LOW); digitalWrite(_enable_pin, LOW); if (_rw_pin != 255) { digitalWrite(_rw_pin, LOW); } //put the LCD into 4 bit or 8 bit mode if (! (_displayfunction & LCD_8BITMODE)) { // this is according to the hitachi HD44780 datasheet // figure 24, pg 46 // we start in 8bit mode, try to set 4 bit mode write4bits(0x03); delayMicroseconds(4500); // wait min 4.1ms // second try write4bits(0x03); delayMicroseconds(4500); // wait min 4.1ms // third go! write4bits(0x03); delayMicroseconds(150); // finally, set to 4-bit interface write4bits(0x02); } else { // this is according to the hitachi HD44780 datasheet // page 45 figure 23 // Send function set command sequence command(LCD_FUNCTIONSET | _displayfunction); delayMicroseconds(4500); // wait more than 4.1ms // second try command(LCD_FUNCTIONSET | _displayfunction); delayMicroseconds(150); // third go command(LCD_FUNCTIONSET | _displayfunction); } // finally, set # lines, font size, etc. command(LCD_FUNCTIONSET | _displayfunction); // turn the display on with no cursor or blinking default _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; display(); // clear it off clear(); // Initialize to default text direction (for romance languages) _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; // set the entry mode command(LCD_ENTRYMODESET | _displaymode);}/********** high level commands, for the user! */void LiquidCrystal::clear(){ command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero delayMicroseconds(2000); // this command takes a long time!}void LiquidCrystal::home(){ command(LCD_RETURNHOME); // set cursor position to zero delayMicroseconds(2000); // this command takes a long time!}void LiquidCrystal::setCursor(uint8_t col, uint8_t row){ int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; if ( row >= _numlines ) { row = _numlines-1; // we count rows starting w/0 } command(LCD_SETDDRAMADDR | (col + row_offsets[row]));}// Turn the display on/off (quickly)void LiquidCrystal::noDisplay() { _displaycontrol &= ~LCD_DISPLAYON; command(LCD_DISPLAYCONTROL | _displaycontrol);}void LiquidCrystal::display() { _displaycontrol |= LCD_DISPLAYON; command(LCD_DISPLAYCONTROL | _displaycontrol);}// Turns the underline cursor on/offvoid LiquidCrystal::noCursor() { _displaycontrol &= ~LCD_CURSORON; command(LCD_DISPLAYCONTROL | _displaycontrol);}void LiquidCrystal::cursor() { _displaycontrol |= LCD_CURSORON; command(LCD_DISPLAYCONTROL | _displaycontrol);}// Turn on and off the blinking cursorvoid LiquidCrystal::noBlink() { _displaycontrol &= ~LCD_BLINKON; command(LCD_DISPLAYCONTROL | _displaycontrol);}void LiquidCrystal::blink() { _displaycontrol |= LCD_BLINKON; command(LCD_DISPLAYCONTROL | _displaycontrol);}// These commands scroll the display without changing the RAMvoid LiquidCrystal::scrollDisplayLeft(void) { command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);}void LiquidCrystal::scrollDisplayRight(void) { command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);}// This is for text that flows Left to Rightvoid LiquidCrystal::leftToRight(void) { _displaymode |= LCD_ENTRYLEFT; command(LCD_ENTRYMODESET | _displaymode);}// This is for text that flows Right to Leftvoid LiquidCrystal::rightToLeft(void) { _displaymode &= ~LCD_ENTRYLEFT; command(LCD_ENTRYMODESET | _displaymode);}// This will 'right justify' text from the cursorvoid LiquidCrystal::autoscroll(void) { _displaymode |= LCD_ENTRYSHIFTINCREMENT; command(LCD_ENTRYMODESET | _displaymode);}// This will 'left justify' text from the cursorvoid LiquidCrystal::noAutoscroll(void) { _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; command(LCD_ENTRYMODESET | _displaymode);}// Allows us to fill the first 8 CGRAM locations// with custom charactersvoid LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { location &= 0x7; // we only have 8 locations 0-7 command(LCD_SETCGRAMADDR | (location << 3)); for (int i=0; i<8; i++) { write(charmap[i]); }}/*********** mid level commands, for sending data/cmds */inline void LiquidCrystal::command(uint8_t value) { send(value, LOW);}inline size_t LiquidCrystal::write(uint8_t value) { send(value, HIGH); return 1; // assume sucess}/************ low level data pushing commands **********/// write either command or data, with automatic 4/8-bit selectionvoid LiquidCrystal::send(uint8_t value, uint8_t mode) { digitalWrite(_rs_pin, mode); // if there is a RW pin indicated, set it low to Write if (_rw_pin != 255) { digitalWrite(_rw_pin, LOW); } if (_displayfunction & LCD_8BITMODE) { write8bits(value); } else { write4bits(value>>4); write4bits(value); }}void LiquidCrystal::pulseEnable(void) { digitalWrite(_enable_pin, LOW);#ifndef __ARDUINO_X86__ delayMicroseconds(1); #endif digitalWrite(_enable_pin, HIGH);#ifndef __ARDUINO_X86__ delayMicroseconds(1); // enable pulse must be >450ns#endif digitalWrite(_enable_pin, LOW); delayMicroseconds(100); // commands need > 37us to settle}void LiquidCrystal::write4bits(uint8_t value) { for (int i = 0; i < 4; i++) { digitalWrite(_data_pins[i], (value >> i) & 0x01); } pulseEnable();}void LiquidCrystal::write8bits(uint8_t value) { for (int i = 0; i < 8; i++) { digitalWrite(_data_pins[i], (value >> i) & 0x01); } pulseEnable();}
/** ****************************************************************************** * @file DMA/ADC_TIM1/main.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main program body ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/#include "stm32f10x.h"/** @addtogroup STM32F10x_StdPeriph_Examples * @{ *//** @addtogroup DMA_ADC_TIM1 * @{ */ /* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*/#define ADC1_DR_Address 0x4001244C#define TIM1_CCR1_Address 0x40012C34#define DAC_DHR12RD_Address 0x40007420#define DAC_DHR12R1 0x40007408#define BUFFER_SIZE 1024#define ADC_PERIOD_TIM 2000#define DAC_PERIOD_TIM 1000/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/ADC_InitTypeDef ADC_InitStructure;DAC_InitTypeDef DAC_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;DMA_InitTypeDef DMA_InitStructure; uint16_t mem_buffer[BUFFER_SIZE];/* Private function prototypes -----------------------------------------------*/void RCC_Configuration(void);void GPIO_Configuration(void); /* Private functions ---------------------------------------------------------*//** * @brief Main program * @param None * @retval None */int main(void){ /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); /* DMA1 Channel5 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&mem_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); /* Enable DMA1 Channel5 */ DMA_Cmd(DMA1_Channel5, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 RegularChannelConfig Test */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); /* TIM1 configuration ------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = ADC_PERIOD_TIM; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Enable TIM1 */ TIM_Cmd(TIM1, ENABLE); /* Enable TIM1 DMA interface */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = DAC_PERIOD_TIM; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM2 TRGO selection */ TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); /* DAC channel1 Configuration */ DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); /* DAC channel2 Configuration */ DAC_Init(DAC_Channel_2, &DAC_InitStructure);#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL /* DMA2 channel4 configuration */ DMA_DeInit(DMA2_Channel4);#else /* DMA1 channel4 configuration */ DMA_DeInit(DMA1_Channel4);#endif DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&mem_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL DMA_Init(DMA2_Channel4, &DMA_InitStructure); /* Enable DMA2 Channel4 */ DMA_Cmd(DMA2_Channel4, ENABLE);#else DMA_Init(DMA1_Channel4, &DMA_InitStructure); /* Enable DMA1 Channel4 */ DMA_Cmd(DMA1_Channel4, ENABLE);#endif /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is automatically connected to the DAC converter. */ DAC_Cmd(DAC_Channel_1, ENABLE); /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is automatically connected to the DAC converter. */ DAC_Cmd(DAC_Channel_2, ENABLE); /* Enable DMA for DAC Channel2 */ DAC_DMACmd(DAC_Channel_2, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1) { }}/** * @brief Configures the different system clocks. * @param None * @retval None */void RCC_Configuration(void){ /* ADCCLK = PCLK2/8 */ RCC_ADCCLKConfig(RCC_PCLK2_Div8); /* Enable peripheral clocks ------------------------------------------------*/ /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable GPIOA, GPIOC, ADC1 and TIM1 Periph clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE); /* Enable peripheral clocks ------------------------------------------------*/#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL /* DMA2 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);#else /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);#endif /* GPIOA Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* DAC Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); /* TIM2 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);}/** * @brief Configures the different GPIO ports. * @param None * @retval None */void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; /* Configure TIM1 Channel1 output */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure ADC Channel14 as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure);}#ifdef USE_FULL_ASSERT/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t* file, uint32_t line){ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { }}#endif/** * @} */ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/