📄 adc_main.c
字号:
/*
* File: main.c
* Purpose: Main process
*
*/
#include "common.h"
#include "uif.h"
/********************************************************************/
/*
* Setup user interface
*/
/* Defining command prompt characters as ADC */
const char PROMPT[] = "ADC> ";
/* Defining the different commands */
void cmd_offset (int, char **);
void cmd_dump (int, char **);
void cmd_disable (int, char **);
void cmd_average (int, char **);
void cmd_start (int, char **);
void cmd_stop (int, char **);
void cmd_sleep (int, char **);
void cmd_zero (int, char **);
void cmd_adlst1 (int, char **);
void cmd_adlst2 (int, char **);
void cmd_adllmt (int, char **);
void cmd_adhlmt (int, char **);
/* Filling the command table */
UIF_CMD UIF_CMDTAB[] =
{
UIF_CMDS_ALL
{"offset",0,2,0,cmd_offset,"Channel & Offset Amount","<ch> <offset>"},
{"dump",0,0,0,cmd_dump,"Display ADC registers",""},
{"disable",0,1,0,cmd_disable,"Disable register(s) 0-7","<ch>"},
{"average",0,0,0,cmd_average,"Average x Conversions"},
{"start",0,0,0,cmd_start,"Start Conversions"},
{"stop",0,0,0,cmd_stop,"Stop conversions"},
{"sleep",0,0,0,cmd_sleep,"Sleep conversion test"},
{"zero",0,3,0,cmd_zero,"Zero Cross Enable","<ch> <offset>"},
{"adlst1",0,3,0,cmd_adlst1,"Channel List 1 Register","<ch> <sample>"},
{"adlst2",0,3,0,cmd_adlst2,"Channel List 2 Register","<ch> <sample>"},
{"adllmt",0,3,0,cmd_adllmt,"Low Limit Register","<ch> <offset>"},
{"adhlmt",0,3,0,cmd_adhlmt,"High Limit Register","<ch> <offset>"},
};
/* Defining the different set/show commands */
void setshow_chncfg (int, char **);
void setshow_smode (int, char **);
/* Filling the set/show command table */
UIF_SETCMD UIF_SETCMDTAB[2];
UIF_SETCMD UIF_SETCMDTAB[] =
{
{"chncfg", 0,1,setshow_chncfg,"set/show, <chncfg> <mode>"},
{"smode", 0,1,setshow_smode,"set/show, <smode> <mode>"},
};
const int UIF_NUM_CMD = UIF_CMDTAB_SIZE;
const int UIF_NUM_SETCMD = UIF_SETCMDTAB_SIZE;
int running_in_sram;
int baud = TERMINAL_BAUD;
#define PLL_DISABLE (0x0001)
/********************************************************************/
void
main (void)
{
extern char __DATA_ROM[];
extern char __DATA_RAM[];
mcf5xxx_irq_enable();
printf("\n");
printf("**************************************************\n");
printf("* *\n");
printf("* ADC Utility *\n");
printf("* *\n");
printf("**************************************************\n");
printf(HELPMSG);
printf("\n");
/* Initialize the CRTL1 register to all 0's */
MCF_ADC_CTRL1 = 0;
/* Setting divisor in CTRL2 register */
MCF_ADC_CTRL2 = MCF_ADC_CTRL2_DIV(3);
/* Setting PortAN as ADC functionality */
MCF_GPIO_PANPAR |= MCF_GPIO_PANPAR_PANPAR0
| MCF_GPIO_PANPAR_PANPAR1
| MCF_GPIO_PANPAR_PANPAR2
| MCF_GPIO_PANPAR_PANPAR3
| MCF_GPIO_PANPAR_PANPAR4
| MCF_GPIO_PANPAR_PANPAR5
| MCF_GPIO_PANPAR_PANPAR6
| MCF_GPIO_PANPAR_PANPAR7;
/* Setting Power Register appropriately */
MCF_ADC_POWER = MCF_ADC_POWER_PUDELAY(4);
/* Command Prompt */
while (TRUE)
{
printf(PROMPT);
run_cmd();
}
}
/*****************************************************************************/
/* Interrupt handler sequence for Sleep Command */
__interrupt__
void
dtim0_handler(void)
{
/* Reset the system clock */
clock_lpd(1);
clock_pll(REF_CLK_KHZ, sys_clk_khz, 0);
/* Turn on UART0 clock */
MCF_PMM_PPMRH = MCF_PMM_PPMRH & ~MCF_PMM_PPMRL_CDUART0;
/* Turn on ADC clock */
MCF_PMM_PPMRH = MCF_PMM_PPMRH &~ MCF_PMM_PPMRH_CDADC;
/* Stop conversions after doing first conversion */
MCF_ADC_ADSDIS = MCF_ADC_ADSDIS_DS1;
/* Clear stop bit */
MCF_ADC_CTRL1 &= ~MCF_ADC_CTRL1_STOP0;
/* Set start bit */
MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_START0;
/* Waiting for Ready bits to be set */
while (!(MCF_ADC_ADSTAT & MCF_ADC_ADSTAT_RDY0))
{};
/* Set stop bit */
MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_STOP0;
/* Shutting off ADC clock */
MCF_PMM_PPMRH != MCF_PMM_PPMRH_CDADC;
/* Diplay the ADC result register for the conversion */
printf("\tADRSLT0 = %04X\n", (MCF_ADC_ADRSLT0));
/* Wait for the UART to finish transmitting */
while(!(MCF_UART_UCSR(TERMINAL_PORT) & MCF_UART_USR_TXEMP)) {};
/*
* Turning off PLL, dividing clock by 32768 to get the lowest
* frequency possible
*/
clock_pll(REF_CLK_KHZ, 0, PLL_DISABLE);
clock_lpd(32768);
/* Resetting Counter */
MCF_DTIM0_DTCN = 0;
MCF_DTIM0_DTER = MCF_DTIM_DTER_REF;
}
/*
* The sleep command puts the processor in to the lowest power stop mode,
* waking the processor up once a second, doing one A/D conversion,
* displaying the result of the conversion, and going back to low power
* mode.
*/
void
cmd_sleep (int argc, char **argv)
{
int i, count;
/* Resetting CTRL1 register to 0 */
MCF_ADC_CTRL1 = 0;
printf("Running test\n");
/* Wait for the UART to finish transmitting */
while(!(MCF_UART_UCSR(TERMINAL_PORT) & MCF_UART_USR_TXEMP)) {};
/* Change the LEDs that are on to show its working */
board_led_display(6);
/* Turn off all module clocks except GPIO, UART0 and INTC0 */
MCF_PMM_PPMRH = 0
// | MCF_PMM_PPMRH_CDPORTS
| MCF_PMM_PPMRH_CDEPORT
| MCF_PMM_PPMRH_CDPIT0
| MCF_PMM_PPMRH_CDPIT1
| MCF_PMM_PPMRH_CDADC
| MCF_PMM_PPMRH_CDGPT
| MCF_PMM_PPMRH_CDPWM
| MCF_PMM_PPMRH_CDFCAN;
MCF_PMM_PPMRL = 0
| MCF_PMM_PPMRL_CDEIM
| MCF_PMM_PPMRL_CDDMA
// | MCF_PMM_PPMRL_CDUART0
| MCF_PMM_PPMRL_CDUART1
| MCF_PMM_PPMRL_CDUART2
| MCF_PMM_PPMRL_CDI2C
| MCF_PMM_PPMRL_CDQSPI
// | MCF_PMM_PPMRL_CDDTIM0
| MCF_PMM_PPMRL_CDDTIM1
| MCF_PMM_PPMRL_CDDTIM2
| MCF_PMM_PPMRL_CDDTIM3;
/*
* Determine which memory the code is running from (SRAM of Flash)
* and turn off other memory to save power
*/
if (running_in_sram)
{
/* Disable clock to CFM */
MCF_PMM_PPMRH |= MCF_PMM_PPMRH_CDCFM;
}
else
/* Disable SRAM instruction accesses */
mcf5xxx_wr_rambar1(SRAM_ADDRESS + 0x35);
/* Setting Interrupt Controller priority and level */
MCF_INTC_ICR(19) = 0
| MCF_INTC_ICR_IP(7)
| MCF_INTC_ICR_IL(1);
/* Unmasking the corresponding interrupt mask for DTIM0 */
MCF_INTC_IMRL &= ~(0
| MCF_INTC_IMRL_MASK19
| MCF_INTC_IMRL_MASKALL);
mcf5xxx_set_handler(64 + 19, (ADDRESS)dtim0_handler);
mcf5xxx_irq_enable();
/* Enable DMA Timer 0 */
/*
* Change the value of the DTRR (value in parenthesis; currently
* set to 175) to increase or decrease frequency that the processor
* comes out of sleep mode; it's currently set to come out of sleep
* and do converstion approximately once every second. The timing of
* interrupt depends on several variables, such as the frequency at
* which the processor is running
*/
/* Setting the DMA Timer 0 registers accordingly */
MCF_DTIM0_DTRR = (175);
MCF_DTIM0_DTER = MCF_DTIM_DTER_REF;
MCF_DTIM0_DTMR = 0
| MCF_DTIM_DTMR_PS(0)
| MCF_DTIM_DTMR_ORRI
| MCF_DTIM_DTMR_OM
| MCF_DTIM_DTMR_FRR
| MCF_DTIM_DTMR_CLK_DIV1;
/* Putting processor in to Doze Mode */
MCF_PMM_LPCR = MCF_PMM_LPCR_LPMD_DOZE;
/* Disable the PLL */
clock_pll(REF_CLK_KHZ, 0, PLL_DISABLE);
clock_lpd(32768);
/* sys clock now = (8MHz / 32768) = 244 Hz */
/* Number of times to execute the sleep/wake-up loop */
count = 2;
while(1)
{
/* Turn on the Timer */
MCF_DTIM0_DTMR |= MCF_DTIM_DTMR_RST;
/* Execute the stop instruction */
stop_2000();
if (!--count)
{
/* Turn off the Timer */
MCF_DTIM0_DTMR = 0;
mcf5xxx_irq_disable();
/* Reset the system clock */
clock_lpd(1);
clock_pll(REF_CLK_KHZ, sys_clk_khz, 0);
/* Turning all module clocks back on */
MCF_PMM_PPMRH = 0;
MCF_PMM_PPMRL = 0;
/* Turn LEDs back on */
board_led_display(15);
printf("Test complete\n");
break;
}
}
}
/***************************************************************************/
/*
* This command will find the average of x conversions (defined by data)
* on one A/D channel (AN0 in this example). It does so by accumulating
* the results of each of the conversions, then dividing by the number
* of conversions that were done to find the average.
*/
void
cmd_average (int argc, char **argv)
{
/* Making declarations */
int i;
int data[1000];
int avg = 0;
/* Loop for doing conversions */
/*
* Change the value from 1000 to a desired value if you would like
* to use a different number of conversions for the average test
*/
for (i = 0; i < 1000; i++)
{
/* Clear stop bit */
MCF_ADC_CTRL1 &= ~MCF_ADC_CTRL1_STOP0;
/* Set start bit */
MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_START0;
/* Waiting for "Ready" bit to be set */
while (!(MCF_ADC_ADSTAT & MCF_ADC_ADSTAT_RDY0))
{};
/* Array of comversions being done on AN0 */
data[i] = (MCF_ADC_ADRSLT0 >> 3);
/* Set stop bit */
MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_STOP0;
}
/*
* Dividing by the number of measurements to determine the average
* The value for i here must match the value of i in previous "for"
* loop
*/
for(i = 0; i < 1000; i++)
{
/* Displaying the value of each conversion */
/* Uncomment the following line to see the value of each conversion */
/* printf("data [%d] = %04d\n",i,data[i]); */
/* Running cumulation of conversions */
avg += data[i];
}
/* Displaying the average */
/* The divider here must match the previous values of i */
printf("\nAverage = 0x%04d\n",avg/1000);
}
/*********************************************************************/
/*
* The offset command allows you to set the voltage offset for
* conversions. When setting an offset, it should be entered in
* decimal form.
*/
void
cmd_offset (int argc, char **argv)
{
int i, success, offset;
/*
* If not the right number of arguments for the offset command,
* display the current offset value for all 8 A/D channels
*/
if (argc == 0 || argc == 1)
{
for (i = 0; i < 8; i++ )
{
printf("OFFSET%d = %#04X (%d)\n", i, MCF_ADC_ADOFS(i)>>3, MCF_ADC_ADOFS(i)>>3);
}
}
else
{
/* If correct number of arguments, get channel for the offset */
i = get_value(argv[1],&success,10);
if (success == 0 || i > 7 || i < 0)
{
/* If incorrect range for channel, display error message */
printf(INVALUE,argv[1]);
printf(" Value must be between 0 and 7\n");
return;
}
/* Get the value of offset */
offset = get_value(argv[2],&success,10);
if (success == 0 || offset > 4095 || offset < 0)
{
/* If incorrect range for offset, display error message */
printf(INVALUE,argv[2]);
printf(" Value must be between 0 and 4095\n");
return;
}
/* Set the offset to the appropriate channel */
MCF_ADC_ADOFS(i) = MCF_ADC_ADOFS_OFFSET(offset);
}
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -