Note that an enum is basically just a set of constants of ordinal type. If you just write:
type
TTest = (T1, T2, T3);
Basically T1 is just the constant 0, T2 is 1 and T3 is 2. You can associate values with these constants directly, as in my example:
type
TTest = (TestA = 'A', TestB, TestD = 'D');
Because char is an ordinal datatype, TestA is basically just a constant for the char A, or in numeric values the value 65, TestB is the next value, so 'B' or numeric 66, and TestD would be the next value (which is 'C'), but because I specifically set it to 'D', it now "skips" 'C'.
So after all this enum is just a set of char (or int) constants, and you can simply convert between them with casts like TTest('A') is TestA, ord(TestA) is 65 and Char(TestA) is 'A'.
If you want to directly look up the name of the enum, you can do this with RTTI or other compiler Features (like ReadStr) as shown in the first few posts. But note that this is a runtime lookup table, while when you are just using ordinals as the underlying values (as shown above) no runtime code is required, as this is just compiletime typechecking. But you are not restricted to ordinals (i.e. char), but may also use full strings