adc_ctrl.rmh
来自「和picoblaze完全兼容的mcu ip core」· RMH 代码 · 共 1,582 行 · 第 1/5 页
RMH
1,582 行
// #93: ;Special Register usage// #94: ;// #95: ;// #96: ;// #97: ;Scratch Pad Memory Locations// #98: ;// #99: ;Values read from the A/D converter// #100: ;// #101: CONSTANT(ADC0_lsb,0) ;ADC Channel 0 value LS-Byte// #102: CONSTANT(ADC0_msb,1) ; MS-Byte// #103: ;// #104: CONSTANT(ADC1_lsb,2) ;ADC Channel 1 value LS-Byte// #105: CONSTANT(ADC1_msb,3) ; MS-Byte// #106: ;// #107: ;Amplifier gain settings.// #108: ;// #109: ;Stored value is the 4-bit code for gain setting// #110: ; Code 1 2 3 4 5 6 7// #111: ; Gain -1 -2 -5 -10 -20 -50 -100// #112: CONSTANT(amp_A_gain,4) ;Amplifier A gain value// #113: CONSTANT(amp_B_gain,5) ;Amplifier B gain value// #114: ;// #115: ;Sample counter used to give activity indication on LEDs// #116: ;// #117: CONSTANT(sample_count,6) ;8-bit counter LS-Byte// #118: ;// #119: CONSTANT(decimal0,7) ;5 digit decimal value// #120: CONSTANT(decimal1,8)// #121: CONSTANT(decimal2,9)// #122: CONSTANT(decimal3,10)// #123: CONSTANT(decimal4,11)// #124: ;// #125: ;// #126: ;// #127: ;// #128: ;Useful data constants// #129: ;// #130: CONSTANT(VREF_lsb,114) ;Reference voltage in milli-volts// #131: CONSTANT(VREF_msb,6) ;Nominal value 1.65v so value is 1650 (0672 hex)// #132: ;// #133: ;Constant to define a software delay of 1us. This must be adjusted to reflect the// #134: ;clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the// #135: ;calculation highly predictable. The '6' in the following equation even allows for// #136: ;'CALL delay_1us' instruction in the initiating code.// #137: ;// #138: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz// #139: ;// #140: ;Example: For a 50MHz clock the constant value is (10-6)/4 = 11 (0B Hex).// #141: ;For clock rates below 10MHz the value of 1 must be used and the operation will// #142: ;become lower than intended.// #143: ;// #144: CONSTANT(delay_1us_constant,11)// #145: ;// #146: ;// #147: ;// #148: ;ASCII table// #149: ;// #150: CONSTANT(character_a,97)// #151: CONSTANT(character_b,98)// #152: CONSTANT(character_c,99)// #153: CONSTANT(character_d,100)// #154: CONSTANT(character_e,101)// #155: CONSTANT(character_f,102)// #156: CONSTANT(character_g,103)// #157: CONSTANT(character_h,104)// #158: CONSTANT(character_i,105)// #159: CONSTANT(character_j,106)// #160: CONSTANT(character_k,107)// #161: CONSTANT(character_l,108)// #162: CONSTANT(character_m,109)// #163: CONSTANT(character_n,110)// #164: CONSTANT(character_o,111)// #165: CONSTANT(character_p,112)// #166: CONSTANT(character_q,113)// #167: CONSTANT(character_r,114)// #168: CONSTANT(character_s,115)// #169: CONSTANT(character_t,116)// #170: CONSTANT(character_u,117)// #171: CONSTANT(character_v,118)// #172: CONSTANT(character_w,119)// #173: CONSTANT(character_x,120)// #174: CONSTANT(character_y,121)// #175: CONSTANT(character_z,122)// #176: CONSTANT(character_A,65)// #177: CONSTANT(character_B,66)// #178: CONSTANT(character_C,67)// #179: CONSTANT(character_D,68)// #180: CONSTANT(character_E,69)// #181: CONSTANT(character_F,70)// #182: CONSTANT(character_G,71)// #183: CONSTANT(character_H,72)// #184: CONSTANT(character_I,73)// #185: CONSTANT(character_J,74)// #186: CONSTANT(character_K,75)// #187: CONSTANT(character_L,76)// #188: CONSTANT(character_M,77)// #189: CONSTANT(character_N,78)// #190: CONSTANT(character_O,79)// #191: CONSTANT(character_P,80)// #192: CONSTANT(character_Q,81)// #193: CONSTANT(character_R,82)// #194: CONSTANT(character_S,83)// #195: CONSTANT(character_T,84)// #196: CONSTANT(character_U,85)// #197: CONSTANT(character_V,86)// #198: CONSTANT(character_W,87)// #199: CONSTANT(character_X,88)// #200: CONSTANT(character_Y,89)// #201: CONSTANT(character_Z,90)// #202: CONSTANT(character_0,48)// #203: CONSTANT(character_1,49)// #204: CONSTANT(character_2,50)// #205: CONSTANT(character_3,51)// #206: CONSTANT(character_4,52)// #207: CONSTANT(character_5,53)// #208: CONSTANT(character_6,54)// #209: CONSTANT(character_7,55)// #210: CONSTANT(character_8,56)// #211: CONSTANT(character_9,57)// #212: CONSTANT(character_colon,58)// #213: CONSTANT(character_stop,46)// #214: CONSTANT(character_semi_colon,59)// #215: CONSTANT(character_minus,45)// #216: CONSTANT(character_divide,47) ;'/'// #217: CONSTANT(character_plus,43)// #218: CONSTANT(character_comma,44)// #219: CONSTANT(character_less_than,60)// #220: CONSTANT(character_greater_than,62)// #221: CONSTANT(character_equals,61)// #222: CONSTANT(character_space,32)// #223: CONSTANT(character_CR,13) ;carriage return// #224: CONSTANT(character_question,63) ;'?'// #225: CONSTANT(character_dollar,36)// #226: CONSTANT(character_exclaim,33) ;'!'// #227: CONSTANT(character_BS,8) ;Back Space command character// #228: ;// #229: ;// #230: ;// #231: ;// #232: ;// #233: ;// #234: ;Initialise the system// #235: ;// #236: ;// @000 #237: [cold_start]3011f // @000 #237: CALL(SPI_init) ;initialise SPI bus ports301fb // @001 #238: CALL(LCD_reset) ;initialise LCD display// #239: ;// #240: ;Write welcome message to LCD display// #241: ;00510 // @002 #242: LOAD(s5,16) ;Line 1 position 030211 // @003 #243: CALL(LCD_cursor)3014e // @004 #244: CALL(disp_PicoBlaze) ;Display 'PicoBlaze Inside'00523 // @005 #245: LOAD(s5,35) ;Line 2 position 330211 // @006 #246: CALL(LCD_cursor)30161 // @007 #247: CALL(disp_ADC_Control)301b3 // @008 #248: CALL(delay_1s) ;wait 5 seconds301b3 // @009 #249: CALL(delay_1s)301b3 // @00a #250: CALL(delay_1s)301b3 // @00b #251: CALL(delay_1s)301b3 // @00c #252: CALL(delay_1s)3020c // @00d #253: CALL(LCD_clear) ;Clear display// #254: ;00000 // @00e #255: LOAD(s0,0) ;clear event counter2e006 // @00f #256: STORE(s0,sample_count)// #257: ;// #258: ;// #259: ;// #260: ;00001 // @010 #261: LOAD(s0,1) ;set initial amplifier gain to 1 on both channels2e004 // @011 #262: STORE(s0,amp_A_gain)2e005 // @012 #263: STORE(s0,amp_B_gain)34092 // @013 #264: JUMP(new_gain_set) ;set, display the initial gain and enable interrupts// #265: ;// #266: ;// #267: ;The program is interrupt driven to maintain an 8KHz sample rate. The main body// #268: ;of the program waits for an interrupt to occur. The interrupt updates all four// #269: ;analogue outputs with values stored in scratch pad memory. This takes approximately// #270: ;58us of the 125us available between interrupts. The main program then prepares// #271: ;new values for the analogue outputs (in less than 67us) before waiting for the// #272: ;next interrupt.// #273: ;// #274: ;// @014 #275: [warm_start]00fff // @014 #275: LOAD(sF,FF) ;flag set and wait for interrupt to be serviced3c001 // @015 #276: ENABLE(INTERRUPT) ;normal operation// @016 #277: [wait_int]04e00 // @016 #277: INPUT(sE,switch_port) ;test for button press changes to amplifier gain12e01 // @017 #278: TEST(sE,BTN_north) ;sE used as this in not effected by ISR35486 // @018 #279: JUMP(NZ,gain_increase)12e04 // @019 #280: TEST(sE,BTN_south)3548d // @01a #281: JUMP(NZ,gain_decrease)14fff // @01b #282: COMPARE(sF,FF) ;wait for interrupt35016 // @01c #283: JUMP(Z,wait_int) ;interrupt clears the flag// #284: ;// #285: ;// #286: ;// #287: ;Drive LEDs with simple binary count of the samples to indicate// #288: ;that the design is active.// #289: ;06006 // @01d #290: FETCH(s0,sample_count) ;increment counter18001 // @01e #291: ADD(s0,1)2e006 // @01f #292: STORE(s0,sample_count)2c080 // @020 #293: OUTPUT(s0,LED_port) ;count increments at 1Hz// #294: ;// #295: ;// #296: ;Display the A/D Channel 0 value as hex on LCD// #297: ;0052c // @021 #298: LOAD(s5,44) ;Line 2 position 1230211 // @022 #299: CALL(LCD_cursor)06001 // @023 #300: FETCH(s0,ADC0_msb)30199 // @024 #301: CALL(disp_hex_byte)06000 // @025 #302: FETCH(s0,ADC0_lsb)30199 // @026 #303: CALL(disp_hex_byte)// #304: ;// #305: ;// #306: ;// #307: ;Convert A/D channel 0 value to decimal voltage// #308: ;// #309: ;The 14-bit signed value from the A/D (sign extended to 16-bits)// #310: ;relates to a voltage in the range -1.25v to +1.25v at the input// #311: ;to the A/D converter relative to the 1.65v mid-rail reference point.// #312: ;// #313: ;The 14-bit value can be translated into the -1.25v to +1.25v using the// #314: ;simple equation...// #315: ;// #316: ; ADin = AD_value x 1.25/8192// #317: ;// #318: ;It is possible to scale the AD_value by 1.25/8192 using a fixed point// #319: ;representation.// #320: ;// #321: ;However, it is also possible to scale it by another factor at the// #322: ;same time which nicely converts to a binary value which is readily// #323: ;converted to decimal. This can be achieved by example...// #324: ;// #325: ;For an input to the A/D converter of +1.25v relative to the reference,// #326: ;the A/D will output the maximum conversion of 1FFF (+8191).// #327: ;// #328: ;In this case we would like to have the result value +1.250v which can be represented// #329: ;by the integer value +1250 with appropiate positioning of the decimal point.// #330: ;The constant to achieve this conversion is +1250/8191=+0.152606...// #331: ;Also a number requiring fixed point representation but how many bits to use?// #332: ;// #333: ;The way to resolve this is to realise that a multiplication will be// #334: ;performed and it would be nice if the +1250 result ended up in a register pair.// #335: ;So if we perform a 16x16-bit multiplication such that the upper 16-bits of// #336: ;the 32-bit result is the required value, then everything will resolve itself.// #337: ;// #338: ;Hence the constant required is actually (1250x(2^16))/8191=+10001 (2711 hex).// #339: ;// #340: ;Using the example 1FFF x 2711 = 04E1F8EF// #341: ; of which the upper 16-bits = 04E1 (+1249 decimal)// #342: ;// #343: ;Likewise the other limit case is E000 x 2711 = FB1DE000// #344: ; of which the upper 16-bits = FB1D (-1251 decimal)// #345: ;// #346: ;The values can be made perfect by rounding before truncation// #347: ;06200 // @027 #348: FETCH(s2,ADC0_lsb) ;Read A/D channel 0 value06301 // @028 #349: FETCH(s3,ADC0_msb)00011 // @029 #350: LOAD(s0,17) ;scaling value for input to A/D converter00127 // @02a #351: LOAD(s1,39)300e4 // @02b #352: CALL(mult_16x16s) ;[s7,s6,s5,s4]=[s3,s2]x[s1,s0]20506 // @02c #353: SL0(s5) ;round value before truncation1a600 // @02d #354: ADDCY(s6,0)1a700 // @02e #355: ADDCY(s7,0)// #356: ;// #357: ;The register pair [s7,s6] now holds the binary value// #358: ;representing the input level to the A/D converter in milli-volts.// #359: ;This is now displayed on the LCD. Negative values need to be converted to// #360: ;signed magnitude for display.// #361: ;00520 // @02f #362: LOAD(s5,32) ;Line 2 position 030211 // @030 #363: CALL(LCD_cursor)3017f // @031 #364: CALL(disp_AD) ;display A/D=12780 // @032 #365: TEST(s7,128) ;test sign bit of value35436 // @033 #366: JUMP(NZ,neg_AD)0052b // @034 #367: LOAD(s5,character_plus)3403b // @035 #368: JUMP(AD_sign)// @036 #369: [neg_AD]0e6ff // @036 #369: XOR(s6,FF) ;complement [s7,s6] to make positive0e7ff // @037 #370: XOR(s7,FF)18601 // @038 #371: ADD(s6,1)1a700 // @039 #372: ADDCY(s7,0)0052d // @03a #373: LOAD(s5,character_minus)// @03b #374: [AD_sign]301d1 // @03b #374: CALL(LCD_write_data) ;display sign of value30074 // @03c #375: CALL(disp_volts) ;display 4 digit value as X.XXXv// #376: ;// #377: ;Convert A/D channel 0 value to display the VINA decimal voltage// #378: ;// #379: ;The same fundamental technique can be used to convert the 14-bit// #380: ;A/D value into the level at the VINA input except that two more factors// #381: ;must be considered.// #382: ;// #383: ;The first is that the amplifier inverts and has gain. Therefore the// #384: ;VINA input level is opposite polarity and could be a smaller deviation// #385: ;from the mid rail 1.65v reference.// #386: ;// #387: ;Secondly, to display the actual voltage level at the VINA terminal// #388: ;the 1.65v offset must be added.// #389: ;// #390: ;The voltage at the VINA input is therefore...// #391: ;// #392: ; VINA = [AD_value x (1.25/(8192 x G))]+1.65// #393: ;// #394: ;Following the same methodology as for the A/D value, it means that there// #395: ;is a set of scaling factors to deal with the negative gain values.// #396: ;// #397: ; K = (+1250 x (2^16)) / (8191 x G)// #398: ;// #399: ; G K (K Hex)// #400: ; -1 -10001 (D8EF)// #401: ; -2 -5001 (EC77)// #402: ; -5 -2000 (F830)// #403: ; -10 -1000 (FC18)// #404: ; -20 -500 (FE0C)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?